From 47a792e263616953f7b719d05c6e595cb332bdee Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Fri, 12 Apr 2024 12:11:04 +0200 Subject: [PATCH 01/18] OP-263 Add specs --- composer.json | 2 +- spec/Action/CaptureActionSpec.php | 107 +++++++++++++++++ spec/Action/ConvertPaymentActionSpec.php | 94 +++++++++++++++ spec/Action/NotifyActionSpec.php | 126 +++++++++++++++++++++ spec/Action/StatusActionSpec.php | 123 ++++++++++++++++++++ spec/ImojeGatewayFactorySpec.php | 22 ++++ spec/Provider/PaymentTokenProviderSpec.php | 109 ++++++++++++++++++ spec/Resolver/SignatureResolverSpec.php | 98 ++++++++++++++++ 8 files changed, 680 insertions(+), 1 deletion(-) create mode 100644 spec/Action/CaptureActionSpec.php create mode 100644 spec/Action/ConvertPaymentActionSpec.php create mode 100644 spec/Action/NotifyActionSpec.php create mode 100644 spec/Action/StatusActionSpec.php create mode 100644 spec/ImojeGatewayFactorySpec.php create mode 100644 spec/Provider/PaymentTokenProviderSpec.php create mode 100644 spec/Resolver/SignatureResolverSpec.php diff --git a/composer.json b/composer.json index 31ee8fc..912e3f7 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "friends-of-behat/suite-settings-extension": "^1.0", "friends-of-behat/symfony-extension": "^2.1", "friends-of-behat/variadic-extension": "^1.3", - "phpspec/phpspec": "^7.2", + "phpspec/phpspec": "^7.5", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^1.8.1", "phpstan/phpstan-doctrine": "1.3.40", diff --git a/spec/Action/CaptureActionSpec.php b/spec/Action/CaptureActionSpec.php new file mode 100644 index 0000000..f67615a --- /dev/null +++ b/spec/Action/CaptureActionSpec.php @@ -0,0 +1,107 @@ +beConstructedWith($signatureResolver); + } + public function it_should_return_true_when_request_and_model_is_valid( + Capture $request, + ArrayObject $arrayObject + ): void { + $request->getModel()->willReturn($arrayObject); + $this->supports($request)->shouldReturn(true); + } + + public function it_should_return_false_when_model_is_invalid( + Capture $request, + ): void { + $request->getModel()->willReturn(null); + $this->supports($request)->shouldReturn(false); + } + public function it_should_return_false_when_request_invalid( + Request $request, + ): void { + $this->supports($request)->shouldReturn(false); + } + + public function it_executes_correctly_with_valid_request( + Capture $request, + OrderInterface $order, + PaymentInterface $payment, + PaymentSecurityTokenInterface $token, + AddressInterface $address, + CustomerInterface $customer, + ImojeApi $apiClass, + SignatureResolverInterface $signatureResolver, + ): void { + + $data = ['statusImoje' => ImojeApiInterface::NEW_STATUS, 'paymentId' => 123, 'tokenHash'=>'1234sdcsdfxz']; + $request->getModel()->willReturn(new ArrayObject($data)); + + $request->getToken()->willReturn('1234sdcsdfxz'); + $request->getFirstModel()->willReturn($payment); + $request->getToken()->willReturn($token); + + $payment->getOrder()->willReturn($order); + $payment->getId()->willReturn(123); + + $token->getHash()->willReturn('1234sdcsdfxz'); + + $apiClass->getServiceKey()->willReturn('1234sdcsdfxz'); + $order->getBillingAddress()->willReturn($address); + $order->getCustomer()->willReturn($customer); + + + $apiClass->getApiUrl()->willReturn('http://example.com/'); + + $apiClass->getServiceId()->willReturn('1'); + $apiClass->getMerchantId()->willReturn('1'); + $order->getTotal()->willReturn(1000); + $order->getCurrencyCode()->willReturn('EUR'); + $order->getNumber()->willReturn('123'); + $address->getFirstName()->willReturn('John Doe'); + $address->getLastName()->willReturn('Smith'); + $token->getAfterUrl()->willReturn('http://example.com/'); + $customer->getEmail()->willReturn('john@doe.com'); + + $orderData = [ + 'serviceId' => '1', + 'merchantId' => '1', + 'amount' => 1000, + 'currency' => 'EUR', + 'orderId' => '123', + 'customerFirstName' => 'John Doe', + 'customerLastName' => 'Smith', + 'urlReturn' => 'http://example.com/', + 'customerEmail' => 'john@doe.com' + ]; + + $signatureResolver->createSignature($orderData,'1234sdcsdfxz') + ->willReturn('signature'); + + $request->setModel(new ArrayObject($data))->shouldBeCalled(); + $this->setApi($apiClass); + + $this->shouldThrow(HttpPostRedirect::class) + ->during('execute', [$request]); + } +} diff --git a/spec/Action/ConvertPaymentActionSpec.php b/spec/Action/ConvertPaymentActionSpec.php new file mode 100644 index 0000000..abf0df6 --- /dev/null +++ b/spec/Action/ConvertPaymentActionSpec.php @@ -0,0 +1,94 @@ +shouldHaveType(ConvertPaymentAction::class); + } + + function it_implements_imoje_gateway_factory_interface(): void { + $this->shouldHaveType(ActionInterface::class); + } + + public function it_sets_result_from_payment_details_with_non_empty_details( + Convert $request, + PaymentInterface $payment + ): void{ + $request->getSource()->willReturn($payment); + $payment->getDetails()->willReturn(['field' => '123']); + $request->setResult(['field' => '123'])->shouldBeCalled(); + + $this->execute($request); + } + public function it_sets_empty_result_when_payment_details_are_empty( + Convert $request, + PaymentInterface $payment + ): void { + $payment->getDetails()->willReturn([]); + $request->getSource()->willReturn($payment); + $request->setResult([])->shouldBeCalled(); + + $this->execute($request); + } + + public function it_sets_result_when_payment_details_contain_null( + Convert $request, + PaymentInterface $payment + ): void { + $payment->getDetails()->willReturn(['key' => null]); + $request->getSource()->willReturn($payment); + $request->setResult(['key' => null])->shouldBeCalled(); + + $this->execute($request); + } + public function it_should_return_true_when_getTo_and_source_is_valid( + Convert $request, + PaymentInterface $payment + ): void { + $request->getSource()->willReturn($payment); + $request->getTo()->willReturn('array'); + + $this->supports($request)->shouldReturn(true); + } + + public function it_should_return_false_when_source_is_invalid( + Convert $request + ): void { + $request->getSource()->willReturn(null); + $request->getTo()->willReturn('array'); + + $this->supports($request)->shouldReturn(false); + } + + public function it_should_return_false_when_getTo_is_invalid( + Convert $request, + PaymentInterface $payment + ): void { + $request->getSource()->willReturn($payment); + $request->getTo()->willReturn('object'); + + $this->supports($request)->shouldReturn(false); + } + public function it_should_return_false_when_getTo_and_source_is_invalid( + Convert $request, + ) : void { + $request->getSource()->willReturn(null); + $request->getTo()->willReturn('object'); + + $this->supports($request)->shouldReturn(false); + } + public function it_should_return_false_when_request_invalid( + Request $request, + ): void { + $this->supports($request)->shouldReturn(false); + } +} diff --git a/spec/Action/NotifyActionSpec.php b/spec/Action/NotifyActionSpec.php new file mode 100644 index 0000000..880fc9e --- /dev/null +++ b/spec/Action/NotifyActionSpec.php @@ -0,0 +1,126 @@ +beConstructedWith( + $requestStack, + $signatureResolver + ); + } + public function it_should_return_true_when_request_and_request_data_is_valid( + Notify $request, + ArrayObject $arrayObject, + SignatureResolverInterface $signatureResolver, + ImojeApi $api, + Request $httpRequest, + RequestStack $requestStack, + ): void { + $request->getModel()->willReturn($arrayObject); + $requestStack->getCurrentRequest() + ->willReturn($httpRequest); + $api->getServiceKey()->willReturn('1234sdcsdfxz'); + + $signatureResolver->verifySignature($httpRequest, '1234sdcsdfxz') + ->willReturn(true) + ->shouldBeCalled(); + + $this->setApi($api); + $this->supports($request)->shouldReturn(true); + } + + public function it_should_return_false_when_request_and_signature_are_invalid( + Notify $request, + ArrayObject $arrayObject, + SignatureResolverInterface $signatureResolver, + ImojeApi $api, + Request $httpRequest, + RequestStack $requestStack, + ): void { + $request->getModel()->willReturn($arrayObject); + $requestStack->getCurrentRequest()->willReturn($httpRequest); + $api->getServiceKey()->willReturn('1234sdcsdfxz'); + + $signatureResolver->verifySignature($httpRequest, '1234sdcsdfxz') + ->willReturn(false) + ->shouldBeCalled(); + + $this->setApi($api); + $this->supports($request)->shouldReturn(false); + } + + public function it_should_return_false_when_request_is_empty( + Notify $request, + ImojeApi $api, + RequestStack $requestStack, + Request $httpRequest, + ): void { + $request->getModel()->willReturn(null); + $requestStack->getCurrentRequest()->willReturn($httpRequest); + $api->getServiceKey()->willReturn(null); + + $this->supports($request)->shouldReturn(false); + } + + public function it_should_return_false_when_request_is_invalid_and( + Notify $request, + RequestStack $requestStack, + Request $httpRequest, + ): void { + $request->getModel()->willReturn(null); + $requestStack->getCurrentRequest()->willReturn($httpRequest); + + $this->supports($httpRequest)->shouldReturn(false); + } + + public function it_sets_model_status_from_notification_data( + Notify $request, + ArrayObject $arrayObject, + SignatureResolverInterface $signatureResolver, + ImojeApi $api, + Request $httpRequest, + RequestStack $requestStack, + ): void { + $requestStack->getCurrentRequest()->willReturn($httpRequest); + $api->getServiceKey()->willReturn('1234sdcsdfxz'); + + $signatureResolver->verifySignature($httpRequest, '1234sdcsdfxz') + ->willReturn(true) + ->shouldBeCalled(); + + $notificationData = ['transaction' => ['status' => 'new','paymentId' => 1, 'tokenHash'=>'1234sdcsdfxz']]; + $jsonNotificationData = json_encode($notificationData); + $httpRequest->getContent()->willReturn($jsonNotificationData); + + $request->getModel()->willReturn(new ArrayObject([ + 'status' => 'new', + 'paymentId' => 1, + 'tokenHash'=>'1234sdcsdfxz' + ])); + + $request->setModel(new ArrayObject([ + 'status' => 'new', + 'paymentId' => 1, + 'tokenHash'=>'1234sdcsdfxz', + 'statusImoje' => 'new' + ]))->willReturn($arrayObject)->shouldBeCalled(); + + $this->setApi($api); + $this->execute($request); + } + +} diff --git a/spec/Action/StatusActionSpec.php b/spec/Action/StatusActionSpec.php new file mode 100644 index 0000000..2db9fe2 --- /dev/null +++ b/spec/Action/StatusActionSpec.php @@ -0,0 +1,123 @@ +shouldHaveType(StatusAction::class); + } + + public function it_should_implement_interface(): void + { + $this->shouldImplement(ActionInterface::class); + } + + public function it_should_return_new_status( + GetStatusInterface $request, + ): void { + $data = ['statusImoje' => ImojeApiInterface::NEW_STATUS, 'paymentId' => 1]; + + $request->getModel()->willReturn(new ArrayCollection($data)); + $request->markNew()->shouldBeCalled(); + + $this->execute($request); + } + + public function it_should_return_pending_status( + GetStatusInterface $request, + ): void { + $data = ['statusImoje' => ImojeApiInterface::PENDING_STATUS, 'paymentId' => 1]; + + $request->getModel()->willReturn(new ArrayCollection($data)); + $request->markPending()->shouldBeCalled(); + + $this->execute($request); + } + public function it_should_return_cancelled_status( + GetStatusInterface $request, + ): void { + $data = ['statusImoje' => ImojeApiInterface::CANCELLED_STATUS, 'paymentId' => 1, 'tokenHash'=>'dfgdsgxcvxcerf234']; + + $request->getModel()->willReturn(new ArrayCollection($data)); + $request->markCanceled()->shouldBeCalled(); + $data['tokenHash'] = ''; + $request->setModel(new ArrayCollection($data))->shouldBeCalled(); + + $this->execute($request); + } + + public function it_should_return_rejected_status( + GetStatusInterface $request, + ): void { + $data = ['statusImoje' => ImojeApiInterface::REJECTED_STATUS, 'paymentId' => 1, 'tokenHash'=>'dfgdsgxcvxcerf234']; + + $request->getModel()->willReturn(new ArrayCollection($data)); + $request->markFailed()->shouldBeCalled(); + $data['tokenHash'] = ''; + $request->setModel(new ArrayCollection($data))->shouldBeCalled(); + + $this->execute($request); + } + + public function it_should_return_settled_status( + GetStatusInterface $request, + ): void { + $data = ['statusImoje' => ImojeApiInterface::SETTLED_STATUS, 'paymentId' => 1, 'tokenHash'=>'dfgdsgxcvxcerf234']; + + $request->getModel()->willReturn(new ArrayCollection($data)); + $request->markCaptured()->shouldBeCalled(); + + $this->execute($request); + } + + public function it_should_return_unknown_status( + GetStatusInterface $request, + ): void { + $data = ['statusImoje' => 'test', 'paymentId' => 1, 'tokenHash'=>'dfgdsgxcvxcerf234']; + + $request->getModel()->willReturn(new ArrayCollection($data)); + $request->markUnknown()->shouldBeCalled(); + + $this->execute($request); + } + + function it_throws_exception_if_request_not_supported( + GetStatusInterface $request + ): void { + $this->shouldThrow(RequestNotSupportedException::class)->during('execute', [$request]); + } + + function it_returns_true_if_request_is_valid( + GetStatusInterface $request, + ArrayAccess $model + ): void { + $request->getModel()->willReturn($model); + $this->supports($request)->shouldBe(true); + } + + function it_returns_false_if_request_model_is_empty( + GetStatusInterface $request + ): void { + $request->getModel()->willReturn(null); + $this->supports($request)->shouldBe(false); + } + function it_returns_false_if_request_class_not_instanceof_GetStatusInterface( + Request $request + ): void { + $this->supports($request)->shouldBe(false); + } + +} diff --git a/spec/ImojeGatewayFactorySpec.php b/spec/ImojeGatewayFactorySpec.php new file mode 100644 index 0000000..4d04a15 --- /dev/null +++ b/spec/ImojeGatewayFactorySpec.php @@ -0,0 +1,22 @@ +shouldHaveType(ImojeGatewayFactory::class); + } + + function it_implements_imoje_gateway_factory_interface(): void{ + $this->shouldHaveType(GatewayFactoryInterface::class); + } + + +} + diff --git a/spec/Provider/PaymentTokenProviderSpec.php b/spec/Provider/PaymentTokenProviderSpec.php new file mode 100644 index 0000000..e2cda97 --- /dev/null +++ b/spec/Provider/PaymentTokenProviderSpec.php @@ -0,0 +1,109 @@ +beConstructedWith($orderRepository, $paymentTokenRepository); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(PaymentTokenProvider::class); + } + + public function it_should_return_token_correctly( + Request $request, + OrderInterface $order, + PaymentSecurityTokenInterface $token, + PaymentInterface $payment, + RepositoryInterface $orderRepository, + RepositoryInterface $paymentTokenRepository, + ): void { + $orderNumber = 500; + $tokenHash = '3423423453fsxzc'; + + $transactionData = [ + 'transaction' => [ + 'orderId' => $orderNumber, + 'tokenHash' => $tokenHash, + ] + ]; + + $request->getContent() + ->willReturn(json_encode($transactionData)); + + $orderRepository->findOneBy(['number' => $orderNumber]) + ->willReturn($order); + + $order->getPayments() + ->willReturn(new ArrayCollection([ + $payment->getWrappedObject() + ])); + + $payment->getState() + ->willReturn(PaymentInterface::STATE_NEW); + + $payment->getDetails() + ->shouldBeCalled() + ->willReturn(['tokenHash' => $tokenHash]); + + $paymentTokenRepository->findOneBy(['hash' => $tokenHash]) + ->willReturn($token) + ->shouldBeCalled(); + + $this->provideToken($request)->shouldReturn($token); + } + + public function it_should_return_null_if_paymentTokenRepository_is_not_called( + Request $request, + OrderInterface $order, + PaymentInterface $payment, + RepositoryInterface $orderRepository, + ): void { + $orderNumber = 500; + $tokenHash = '3423423453fsxzc'; + + $transactionData = [ + 'transaction' => [ + 'orderId' => $orderNumber, + 'tokenHash' => $tokenHash, + ] + ]; + + $request->getContent() + ->willReturn(json_encode($transactionData)); + + $orderRepository->findOneBy(['number' => $orderNumber]) + ->willReturn($order); + + $order->getPayments() + ->willReturn(new ArrayCollection([ + $payment->getWrappedObject() + ])); + + $payment->getState() + ->willReturn(PaymentInterface::STATE_CANCELLED); + + $payment->getDetails() + ->shouldBeCalled() + ->willReturn(['tokenHash' => $tokenHash]); + + + $this->provideToken($request)->shouldReturn(null); + + } +} diff --git a/spec/Resolver/SignatureResolverSpec.php b/spec/Resolver/SignatureResolverSpec.php new file mode 100644 index 0000000..c6a5226 --- /dev/null +++ b/spec/Resolver/SignatureResolverSpec.php @@ -0,0 +1,98 @@ +shouldHaveType(SignatureResolver::class); + } + + public function it_should_sort_fields_and_build_data_string(): void + { + $fields = [ + 'field1' => 'value1', + 'field2' => 'value2', + ]; + $serviceKey = 'adasvcx3412'; + $expectedDataString = 'field1=value1&field2=value2'; + $expectedHash = hash(ImojeApiInterface::HASHING_ALGORITHM, $expectedDataString . $serviceKey) . ';' . ImojeApiInterface::HASHING_ALGORITHM; + + $this->createSignature($fields, $serviceKey) + ->shouldReturn($expectedHash); + } + public function it_should_return_hash_with_service_key_only_when_fields_are_empty(): void + { + $fields = []; + $serviceKey = 'adasvcx3412'; + $expectedHash = hash(ImojeApiInterface::HASHING_ALGORITHM, $serviceKey) . ';' . ImojeApiInterface::HASHING_ALGORITHM; + + $this->createSignature($fields, $serviceKey)->shouldReturn($expectedHash); + } + + public function it_should_return_hash_without_service_key_when_service_key_is_empty(): void + { + $fields = [ + 'field1' => 'value1', + 'field2' => 'value2', + ]; + $serviceKey = ''; + $expectedDataString = 'field1=value1&field2=value2'; + + $expectedHash = hash(ImojeApiInterface::HASHING_ALGORITHM, $expectedDataString ) . ';' . ImojeApiInterface::HASHING_ALGORITHM; + + $this->createSignature($fields, $serviceKey) + ->shouldReturn($expectedHash); + } + + public function it_should_return_true_if_signatures_match( + Request $request + ): void { + $serviceKey = 'adasvcx3412'; + $body = 'test.jpg'; + $exampleHash = hash('sha256',sprintf('test.jpg%s',$serviceKey)); + $headerSignature = sprintf('alg=sha256;signature=%s',$exampleHash); + + $request->getContent()->willReturn($body); + $request->headers = new \Symfony\Component\HttpFoundation\HeaderBag(['X-Imoje-Signature' => $headerSignature]); + + $this->verifySignature($request, $serviceKey)->shouldBe(true); + + } + + public function it_should_return_false_if_signatures_not_match( + Request $request + ): void { + $serviceKey = 'adasvcx3412'; + $body = 'test2.jpg'; + $exampleHash = hash('sha256',sprintf('test.jpg%s',$serviceKey)); + $headerSignature = sprintf('alg=sha256;signature=%s',$exampleHash); + + $request->getContent()->willReturn($body); + $request->headers = new \Symfony\Component\HttpFoundation\HeaderBag(['X-Imoje-Signature' => $headerSignature]); + + $this->verifySignature($request, $serviceKey)->shouldBe(false); + + } + + public function it_should_return_false_if_content_is_empty( + Request $request + ): void { + $serviceKey = ''; + $body = ''; + $exampleHash = ''; + $headerSignature = sprintf('alg=sha256;signature=%s',$exampleHash); + + $request->getContent()->willReturn($body); + $request->headers = new \Symfony\Component\HttpFoundation\HeaderBag(['X-Imoje-Signature' => $headerSignature]); + + $this->verifySignature($request, $serviceKey)->shouldBe(false); + + } +} From d6384759e08ff47d3498d99a9b57ae9714d8a50d Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Fri, 12 Apr 2024 15:03:37 +0200 Subject: [PATCH 02/18] OP-263 Add ecs and phpStan + fixes --- .gitignore | 5 + .idea/.gitignore | 8 + .idea/SyliusImojePaywallPlugin.iml | 262 +++++++++++++++ .idea/codeception.xml | 12 + .idea/inspectionProfiles/Project_Default.xml | 8 + .idea/modules.xml | 8 + .idea/php-test-framework.xml | 21 ++ .idea/php.xml | 303 ++++++++++++++++++ .idea/phpspec.xml | 10 + .idea/phpunit.xml | 10 + .idea/vcs.xml | 6 + .php-cs-fixer.dist.php | 13 + composer.json | 3 +- ecs.php | 2 + phpstan.neon | 1 + src/Action/CaptureAction.php | 14 +- src/Action/ConvertPaymentAction.php | 2 +- src/Action/NotifyAction.php | 10 +- src/Action/StatusAction.php | 2 +- src/Api/ImojeApi.php | 3 +- src/Api/ImojeApiInterface.php | 9 +- src/Controller/NotifyController.php | 15 +- .../Type/ImojeGatewayConfigurationType.php | 33 +- src/ImojeGatewayFactory.php | 4 +- src/Provider/PaymentTokenProvider.php | 12 +- src/Resolver/SignatureResolver.php | 9 +- symfony.lock | 12 + 27 files changed, 750 insertions(+), 47 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/SyliusImojePaywallPlugin.iml create mode 100644 .idea/codeception.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/php-test-framework.xml create mode 100644 .idea/php.xml create mode 100644 .idea/phpspec.xml create mode 100644 .idea/phpunit.xml create mode 100644 .idea/vcs.xml create mode 100644 .php-cs-fixer.dist.php diff --git a/.gitignore b/.gitignore index 5cefda9..986c41a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,8 @@ # Symfony CLI https://symfony.com/doc/current/setup/symfony_server.html#different-php-settings-per-project /.php-version /php.ini + +###> friendsofphp/php-cs-fixer ### +/.php-cs-fixer.php +/.php-cs-fixer.cache +###< friendsofphp/php-cs-fixer ### diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/SyliusImojePaywallPlugin.iml b/.idea/SyliusImojePaywallPlugin.iml new file mode 100644 index 0000000..1556cdb --- /dev/null +++ b/.idea/SyliusImojePaywallPlugin.iml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeception.xml b/.idea/codeception.xml new file mode 100644 index 0000000..330f2dd --- /dev/null +++ b/.idea/codeception.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..9a737d3 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..54e6421 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/php-test-framework.xml b/.idea/php-test-framework.xml new file mode 100644 index 0000000..0e401b0 --- /dev/null +++ b/.idea/php-test-framework.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml new file mode 100644 index 0000000..f043b45 --- /dev/null +++ b/.idea/php.xml @@ -0,0 +1,303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/phpspec.xml b/.idea/phpspec.xml new file mode 100644 index 0000000..33107fd --- /dev/null +++ b/.idea/phpspec.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/phpunit.xml b/.idea/phpunit.xml new file mode 100644 index 0000000..4f8104c --- /dev/null +++ b/.idea/phpunit.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..3788194 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,13 @@ +in(__DIR__) + ->exclude('var') +; + +return (new PhpCsFixer\Config()) + ->setRules([ + '@Symfony' => true, + ]) + ->setFinder($finder) +; diff --git a/composer.json b/composer.json index 912e3f7..3083318 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "require-dev": { "behat/behat": "^3.6.1", "behat/mink-selenium2-driver": "^1.4", + "bitbag/coding-standard": "^3.0", "dmore/behat-chrome-extension": "^1.3", "dmore/chrome-mink-driver": "^2.7", "friends-of-behat/mink": "^1.8", @@ -28,7 +29,7 @@ "friends-of-behat/variadic-extension": "^1.3", "phpspec/phpspec": "^7.5", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.8.1", + "phpstan/phpstan": "^1.10", "phpstan/phpstan-doctrine": "1.3.40", "phpstan/phpstan-strict-rules": "^1.3.0", "phpstan/phpstan-webmozart-assert": "^1.2.0", diff --git a/ecs.php b/ecs.php index 3cf43de..16db5bc 100644 --- a/ecs.php +++ b/ecs.php @@ -12,6 +12,8 @@ __DIR__ . '/ecs.php', ]); + putenv('ALLOW_BITBAG_OS_HEADER=0'); + $ecsConfig->import('vendor/sylius-labs/coding-standard/ecs.php'); $ecsConfig->skip([ diff --git a/phpstan.neon b/phpstan.neon index 2235744..e278f59 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,6 +2,7 @@ parameters: level: max reportUnmatchedIgnoredErrors: false checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false paths: - src - tests/Behat diff --git a/src/Action/CaptureAction.php b/src/Action/CaptureAction.php index a791b2a..c811f9c 100644 --- a/src/Action/CaptureAction.php +++ b/src/Action/CaptureAction.php @@ -27,7 +27,7 @@ public function __construct(private readonly SignatureResolverInterface $signatu $this->apiClass = ImojeApi::class; } - public function execute($request) + public function execute($request): void { RequestNotSupportedException::assertSupports($this, $request); $model = $request->getModel(); @@ -50,15 +50,15 @@ public function execute($request) throw new HttpPostRedirect( $this->api->getApiUrl(), - $orderData + $orderData, ); } public function supports($request): bool { return - $request instanceof Capture - && $request->getModel() instanceof ArrayObject; + $request instanceof Capture && + $request->getModel() instanceof ArrayObject; } private function prepareOrderData(OrderInterface $order, PaymentSecurityTokenInterface $token): array @@ -73,10 +73,10 @@ private function prepareOrderData(OrderInterface $order, PaymentSecurityTokenInt $orderData['amount'] = $order->getTotal(); $orderData['currency'] = $order->getCurrencyCode(); $orderData['orderId'] = $order->getNumber(); - $orderData['customerFirstName'] = $billingAddress->getFirstName(); - $orderData['customerLastName'] = $billingAddress->getLastName(); + $orderData['customerFirstName'] = $billingAddress?->getFirstName(); + $orderData['customerLastName'] = $billingAddress?->getLastName(); $orderData['urlReturn'] = $token->getAfterUrl(); - $orderData['customerEmail'] = $customer->getEmail(); + $orderData['customerEmail'] = $customer?->getEmail(); $orderData['signature'] = $this->signatureResolver->createSignature($orderData, $this->api->getServiceKey()); return $orderData; diff --git a/src/Action/ConvertPaymentAction.php b/src/Action/ConvertPaymentAction.php index 4ad81b5..6e7113f 100644 --- a/src/Action/ConvertPaymentAction.php +++ b/src/Action/ConvertPaymentAction.php @@ -19,7 +19,7 @@ public function execute($request): void $request->setResult((array) $details); } - public function supports($request) + public function supports($request): bool { return $request instanceof Convert && diff --git a/src/Action/NotifyAction.php b/src/Action/NotifyAction.php index f641c20..d8cf6ee 100644 --- a/src/Action/NotifyAction.php +++ b/src/Action/NotifyAction.php @@ -22,10 +22,10 @@ final class NotifyAction implements ActionInterface, ApiAwareInterface private Request $request; public function __construct( - private readonly RequestStack $requestStack, + protected RequestStack $requestStack, private readonly SignatureResolverInterface $signatureResolver, ) { - $this->request = $requestStack->getCurrentRequest(); + $this->request = $requestStack->getCurrentRequest() ?? new Request(); $this->apiClass = ImojeApi::class; } @@ -45,8 +45,8 @@ public function execute($request): void public function supports($request): bool { return - $request instanceof Notify - && $request->getModel() instanceof ArrayObject - && $this->signatureResolver->verifySignature($this->request, $this->api->getServiceKey()); + $request instanceof Notify && + $request->getModel() instanceof ArrayObject && + $this->signatureResolver->verifySignature($this->request, $this->api->getServiceKey()); } } diff --git a/src/Action/StatusAction.php b/src/Action/StatusAction.php index 05d0444..ff1340c 100644 --- a/src/Action/StatusAction.php +++ b/src/Action/StatusAction.php @@ -63,6 +63,6 @@ public function supports($request): bool { return $request instanceof GetStatusInterface && $request->getModel() instanceof ArrayAccess - ; + ; } } diff --git a/src/Api/ImojeApi.php b/src/Api/ImojeApi.php index b4cb51b..486fd52 100644 --- a/src/Api/ImojeApi.php +++ b/src/Api/ImojeApi.php @@ -12,7 +12,8 @@ public function __construct( private readonly string $serviceId, private readonly string $serviceKey, private readonly string $authorizationToken, - ) {} + ) { + } public function getApiUrl(): string { diff --git a/src/Api/ImojeApiInterface.php b/src/Api/ImojeApiInterface.php index a79d8ef..b8bf958 100644 --- a/src/Api/ImojeApiInterface.php +++ b/src/Api/ImojeApiInterface.php @@ -1,19 +1,27 @@ execute(new Notify($notifyToken)); return new JsonResponse(['status' => 'ok']); - } else { - throw new NotFoundHttpException('Payment token not found'); } + + throw new NotFoundHttpException('Payment token not found'); } private function createRequestWithToken( Request $request, - PaymentSecurityTokenInterface $token + PaymentSecurityTokenInterface $token, ): Request { $request = Request::create( $token->getTargetUrl(), @@ -49,11 +52,11 @@ private function createRequestWithToken( $request->cookies->all(), $request->files->all(), $request->server->all(), - $request->getContent() + $request->getContent(), ); $request->attributes->add([ - 'payum_token' => $token->getHash() + 'payum_token' => $token->getHash(), ]); return $request; diff --git a/src/Form/Type/ImojeGatewayConfigurationType.php b/src/Form/Type/ImojeGatewayConfigurationType.php index 6e85a32..947d3c0 100644 --- a/src/Form/Type/ImojeGatewayConfigurationType.php +++ b/src/Form/Type/ImojeGatewayConfigurationType.php @@ -16,13 +16,16 @@ final class ImojeGatewayConfigurationType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('environment', ChoiceType::class, [ + ->add( + 'environment', + ChoiceType::class, + [ 'choices' => [ 'bitbag.imoje_plugin.configuration.production' => ImojeApiInterface::PRODUCTION_ENVIRONMENT, 'bitbag.imoje_plugin.configuration.sandbox' => ImojeApiInterface::SANDBOX_ENVIRONMENT, ], - 'label' => 'bitbag.imoje_plugin.configuration.environment' - ] + 'label' => 'bitbag.imoje_plugin.configuration.environment', + ], ) ->add('merchant_id', TextType::class, [ 'label' => 'bitbag.imoje_plugin.configuration.merchant_id', @@ -30,10 +33,10 @@ public function buildForm(FormBuilderInterface $builder, array $options) new NotBlank( [ 'message' => 'bitbag.imoje_plugin.configuration.merchant_id.not_blank', - 'groups' => ['sylius'] - ] + 'groups' => ['sylius'], + ], ), - ] + ], ]) ->add('service_id', TextType::class, [ 'label' => 'bitbag.imoje_plugin.configuration.service_id', @@ -41,10 +44,10 @@ public function buildForm(FormBuilderInterface $builder, array $options) new NotBlank( [ 'message' => 'bitbag.imoje_plugin.configuration.service_id.not_blank', - 'groups' => ['sylius'] - ] + 'groups' => ['sylius'], + ], ), - ] + ], ]) ->add('service_key', TextType::class, [ 'label' => 'bitbag.imoje_plugin.configuration.service_key', @@ -52,10 +55,10 @@ public function buildForm(FormBuilderInterface $builder, array $options) new NotBlank( [ 'message' => 'bitbag.imoje_plugin.configuration.service_key.not_blank', - 'groups' => ['sylius'] - ] + 'groups' => ['sylius'], + ], ), - ] + ], ]) ->add('authorization_token', TextType::class, [ 'label' => 'bitbag.imoje_plugin.configuration.authorization_token', @@ -63,10 +66,10 @@ public function buildForm(FormBuilderInterface $builder, array $options) new NotBlank( [ 'message' => 'bitbag.imoje_plugin.configuration.authorization_token.not_blank', - 'groups' => ['sylius'] - ] + 'groups' => ['sylius'], + ], ), - ] + ], ]); } } diff --git a/src/ImojeGatewayFactory.php b/src/ImojeGatewayFactory.php index fbd9779..c2aa252 100644 --- a/src/ImojeGatewayFactory.php +++ b/src/ImojeGatewayFactory.php @@ -16,8 +16,8 @@ protected function populateConfig(ArrayObject $config): void $config->defaults( [ 'payum.factory_name' => 'imoje', - 'payum.factory_title' => 'Imoje' - ] + 'payum.factory_title' => 'Imoje', + ], ); if (false === (bool) $config['payum.api']) { diff --git a/src/Provider/PaymentTokenProvider.php b/src/Provider/PaymentTokenProvider.php index c4ae7f5..acaea21 100644 --- a/src/Provider/PaymentTokenProvider.php +++ b/src/Provider/PaymentTokenProvider.php @@ -15,7 +15,8 @@ final class PaymentTokenProvider implements PaymentTokenProviderInterface public function __construct( private readonly RepositoryInterface $orderRepository, private readonly RepositoryInterface $paymentTokenRepository, - ) {} + ) { + } public function provideToken(Request $request): ?PaymentSecurityTokenInterface { @@ -25,16 +26,17 @@ public function provideToken(Request $request): ?PaymentSecurityTokenInterface $transactionData = $content['transaction']; $order = $this->getOrder($transactionData); + $payments = $order->getPayments(); - foreach ($order->getPayments() as $payment) { + foreach ($payments as $payment) { $model = $payment->getDetails(); $tokenHash = $model['tokenHash'] ?? null; if ( - null !== $tokenHash - && $payment->getState() !== PaymentInterface::STATE_CANCELLED - && $payment->getState() !== PaymentInterface::STATE_FAILED + null !== $tokenHash && + $payment->getState() !== PaymentInterface::STATE_CANCELLED && + $payment->getState() !== PaymentInterface::STATE_FAILED ) { return $this->getToken($tokenHash); } diff --git a/src/Resolver/SignatureResolver.php b/src/Resolver/SignatureResolver.php index 8f69d9a..5d426f1 100644 --- a/src/Resolver/SignatureResolver.php +++ b/src/Resolver/SignatureResolver.php @@ -18,6 +18,7 @@ public function createSignature(array $fields, string $serviceKey): string $value = http_build_query([$key => $value], '', '&'); $key = ''; } + return $key !== '' ? "$key=$value" : $value; }, array_keys($fields), $fields); @@ -32,9 +33,13 @@ public function verifySignature(Request $request, string $serviceKey): bool $body = $request->getContent(); $parts = []; - parse_str(str_replace([';', '='], ['&', '='], $headerSignature), $parts); - $ownSignature = hash($parts['alg'], $body . $serviceKey); + if($headerSignature !== null ) { + parse_str(str_replace([';', '='], ['&', '='], $headerSignature), $parts); + } + + $algo = is_string($parts['alg']) ? $parts['alg'] : 'sha256'; + $ownSignature = hash($algo, $body . $serviceKey); return $ownSignature === $parts['signature']; } diff --git a/symfony.lock b/symfony.lock index 347b795..f68509b 100644 --- a/symfony.lock +++ b/symfony.lock @@ -61,6 +61,18 @@ "ref": "1e012e04f573524ca83795cd19df9ea690adb604" } }, + "friendsofphp/php-cs-fixer": { + "version": "3.53", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "3.0", + "ref": "be2103eb4a20942e28a6dd87736669b757132435" + }, + "files": [ + ".php-cs-fixer.dist.php" + ] + }, "friendsofsymfony/rest-bundle": { "version": "3.5", "recipe": { From ae50e1ceb520dff429c7b16b8405ae09f617114c Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Mon, 15 Apr 2024 07:27:55 +0200 Subject: [PATCH 03/18] phpStan - fix rest files --- src/Controller/NotifyController.php | 2 +- src/Provider/PaymentTokenProvider.php | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Controller/NotifyController.php b/src/Controller/NotifyController.php index 171d170..24c1541 100644 --- a/src/Controller/NotifyController.php +++ b/src/Controller/NotifyController.php @@ -23,7 +23,7 @@ public function __construct( public function verifyImojeNotification(Request $request): Response { - if (!$request->getContent()) { + if ($request->getContent() === '') { return new Response('', Response::HTTP_NO_CONTENT); } diff --git a/src/Provider/PaymentTokenProvider.php b/src/Provider/PaymentTokenProvider.php index acaea21..25972d5 100644 --- a/src/Provider/PaymentTokenProvider.php +++ b/src/Provider/PaymentTokenProvider.php @@ -26,6 +26,9 @@ public function provideToken(Request $request): ?PaymentSecurityTokenInterface $transactionData = $content['transaction']; $order = $this->getOrder($transactionData); + if ($order == null) { + return null; + } $payments = $order->getPayments(); foreach ($payments as $payment) { @@ -47,11 +50,19 @@ public function provideToken(Request $request): ?PaymentSecurityTokenInterface private function getOrder(array $transactionData): ?OrderInterface { - return $this->orderRepository->findOneBy(['number' => $transactionData['orderId']]); + $order = $this->orderRepository->findOneBy(['number' => $transactionData['orderId']]); + if ($order instanceof OrderInterface) { + return $order; + } + return null; } private function getToken(string $hash): ?PaymentSecurityTokenInterface { - return $this->paymentTokenRepository->findOneBy(['hash' => $hash]); + $token = $this->paymentTokenRepository->findOneBy(['hash' => $hash]); + if ($token instanceof PaymentSecurityTokenInterface) { + return $token; + } + return null; } } From a7fa7ad1ff9bfd049a6279d2c33fd1f75545114b Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Mon, 15 Apr 2024 07:38:14 +0200 Subject: [PATCH 04/18] Update BitBag file header --- spec/Action/CaptureActionSpec.php | 8 ++++++++ spec/Action/ConvertPaymentActionSpec.php | 8 ++++++++ spec/Action/NotifyActionSpec.php | 8 ++++++++ spec/Action/StatusActionSpec.php | 9 ++++++++- spec/ImojeGatewayFactorySpec.php | 8 ++++++++ spec/Provider/PaymentTokenProviderSpec.php | 8 ++++++++ src/Action/CaptureAction.php | 7 +++++++ src/Action/ConvertPaymentAction.php | 7 +++++++ src/Action/NotifyAction.php | 7 +++++++ src/Action/StatusAction.php | 7 +++++++ src/Api/ImojeApi.php | 7 +++++++ src/Api/ImojeApiInterface.php | 7 +++++++ src/BitBagSyliusImojePlugin.php | 7 +++++++ src/Controller/NotifyController.php | 7 +++++++ src/DependencyInjection/BitBagSyliusImojeExtension.php | 7 +++++++ src/Form/Type/ImojeGatewayConfigurationType.php | 7 +++++++ src/ImojeGatewayFactory.php | 7 +++++++ src/Provider/PaymentTokenProvider.php | 7 +++++++ src/Provider/PaymentTokenProviderInterface.php | 7 +++++++ src/Resolver/SignatureResolver.php | 7 +++++++ src/Resolver/SignatureResolverInterface.php | 7 +++++++ 21 files changed, 153 insertions(+), 1 deletion(-) diff --git a/spec/Action/CaptureActionSpec.php b/spec/Action/CaptureActionSpec.php index f67615a..6254916 100644 --- a/spec/Action/CaptureActionSpec.php +++ b/spec/Action/CaptureActionSpec.php @@ -1,5 +1,13 @@ Date: Mon, 15 Apr 2024 12:23:31 +0200 Subject: [PATCH 05/18] update github actions --- .github/workflows/build.yml | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 34b946c..f382043 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -160,10 +160,26 @@ jobs: name: Validate database schema run: (cd tests/Application && bin/console doctrine:schema:validate) - - - name: Run PHPSpec + - name: Run PHPStan + run: vendor/bin/phpstan analyse -c phpstan.neon -l 8 src/ + + - name: Run ECS + run: vendor/bin/ecs check src + + - name: Run PHPSpec run: vendor/bin/phpspec run --ansi -f progress --no-interaction - - - name: Run PHPUnit - run: vendor/bin/phpunit --colors=always + - name: Load fixtures in test application + run: (cd tests/Application && bin/console sylius:fixtures:load -n) + + - name: Failed build Slack notification + uses: rtCamp/action-slack-notify@v2 + if: ${{ failure() && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') }} + env: + SLACK_CHANNEL: ${{ secrets.FAILED_BUILD_SLACK_CHANNEL }} + SLACK_COLOR: ${{ job.status }} + SLACK_ICON: https://github.com/rtCamp.png?size=48 + SLACK_MESSAGE: ':x:' + SLACK_TITLE: Failed build on ${{ github.event.repository.name }} repository + SLACK_USERNAME: ${{ secrets.FAILED_BUILD_SLACK_USERNAME }} + SLACK_WEBHOOK: ${{ secrets.FAILED_BUILD_SLACK_WEBHOOK }} From d73325f802896f54d8244d875cde0705a3f3cbd3 Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Mon, 15 Apr 2024 12:24:05 +0200 Subject: [PATCH 06/18] ECS --- src/Action/CaptureAction.php | 1 - src/Action/ConvertPaymentAction.php | 1 - src/Action/NotifyAction.php | 1 - src/Action/StatusAction.php | 1 - src/Api/ImojeApi.php | 1 - src/Api/ImojeApiInterface.php | 1 - src/BitBagSyliusImojePlugin.php | 1 - src/Controller/NotifyController.php | 1 - .../BitBagSyliusImojeExtension.php | 1 - .../Type/ImojeGatewayConfigurationType.php | 1 - src/ImojeGatewayFactory.php | 1 - src/Provider/PaymentTokenProvider.php | 19 +++++++++---------- .../PaymentTokenProviderInterface.php | 1 - src/Resolver/SignatureResolver.php | 3 +-- src/Resolver/SignatureResolverInterface.php | 1 - 15 files changed, 10 insertions(+), 25 deletions(-) diff --git a/src/Action/CaptureAction.php b/src/Action/CaptureAction.php index e944aa4..70b1f4d 100644 --- a/src/Action/CaptureAction.php +++ b/src/Action/CaptureAction.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Action; diff --git a/src/Action/ConvertPaymentAction.php b/src/Action/ConvertPaymentAction.php index 16396aa..be187f2 100644 --- a/src/Action/ConvertPaymentAction.php +++ b/src/Action/ConvertPaymentAction.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Action; diff --git a/src/Action/NotifyAction.php b/src/Action/NotifyAction.php index a16472f..dd494d9 100644 --- a/src/Action/NotifyAction.php +++ b/src/Action/NotifyAction.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Action; diff --git a/src/Action/StatusAction.php b/src/Action/StatusAction.php index 6071951..d088982 100644 --- a/src/Action/StatusAction.php +++ b/src/Action/StatusAction.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Action; diff --git a/src/Api/ImojeApi.php b/src/Api/ImojeApi.php index 3c134f8..64395fe 100644 --- a/src/Api/ImojeApi.php +++ b/src/Api/ImojeApi.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Api; diff --git a/src/Api/ImojeApiInterface.php b/src/Api/ImojeApiInterface.php index 3cabbc5..6f4e716 100644 --- a/src/Api/ImojeApiInterface.php +++ b/src/Api/ImojeApiInterface.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Api; diff --git a/src/BitBagSyliusImojePlugin.php b/src/BitBagSyliusImojePlugin.php index 3cbd703..2025456 100644 --- a/src/BitBagSyliusImojePlugin.php +++ b/src/BitBagSyliusImojePlugin.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin; diff --git a/src/Controller/NotifyController.php b/src/Controller/NotifyController.php index 03fccd9..6a4f3fc 100644 --- a/src/Controller/NotifyController.php +++ b/src/Controller/NotifyController.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Controller; diff --git a/src/DependencyInjection/BitBagSyliusImojeExtension.php b/src/DependencyInjection/BitBagSyliusImojeExtension.php index 9fe2150..684b70e 100644 --- a/src/DependencyInjection/BitBagSyliusImojeExtension.php +++ b/src/DependencyInjection/BitBagSyliusImojeExtension.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\DependencyInjection; diff --git a/src/Form/Type/ImojeGatewayConfigurationType.php b/src/Form/Type/ImojeGatewayConfigurationType.php index 13c00d2..f8c3b9b 100644 --- a/src/Form/Type/ImojeGatewayConfigurationType.php +++ b/src/Form/Type/ImojeGatewayConfigurationType.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Form\Type; diff --git a/src/ImojeGatewayFactory.php b/src/ImojeGatewayFactory.php index c456ea7..b83a070 100644 --- a/src/ImojeGatewayFactory.php +++ b/src/ImojeGatewayFactory.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin; diff --git a/src/Provider/PaymentTokenProvider.php b/src/Provider/PaymentTokenProvider.php index 3c55164..4b938e1 100644 --- a/src/Provider/PaymentTokenProvider.php +++ b/src/Provider/PaymentTokenProvider.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Provider; @@ -33,9 +32,11 @@ public function provideToken(Request $request): ?PaymentSecurityTokenInterface $transactionData = $content['transaction']; $order = $this->getOrder($transactionData); + if ($order == null) { return null; } + $payments = $order->getPayments(); foreach ($payments as $payment) { @@ -57,19 +58,17 @@ public function provideToken(Request $request): ?PaymentSecurityTokenInterface private function getOrder(array $transactionData): ?OrderInterface { + /** @var OrderInterface|null $order */ $order = $this->orderRepository->findOneBy(['number' => $transactionData['orderId']]); - if ($order instanceof OrderInterface) { - return $order; - } - return null; + + return $order; } private function getToken(string $hash): ?PaymentSecurityTokenInterface { - $token = $this->paymentTokenRepository->findOneBy(['hash' => $hash]); - if ($token instanceof PaymentSecurityTokenInterface) { - return $token; - } - return null; + /** @var PaymentSecurityTokenInterface|null $token */ + $token = $this->paymentTokenRepository->findOneBy(['hash' => $hash]); + + return $token; } } diff --git a/src/Provider/PaymentTokenProviderInterface.php b/src/Provider/PaymentTokenProviderInterface.php index aee8fbf..8ba4481 100644 --- a/src/Provider/PaymentTokenProviderInterface.php +++ b/src/Provider/PaymentTokenProviderInterface.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Provider; diff --git a/src/Resolver/SignatureResolver.php b/src/Resolver/SignatureResolver.php index ed22003..65580d0 100644 --- a/src/Resolver/SignatureResolver.php +++ b/src/Resolver/SignatureResolver.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Resolver; @@ -41,7 +40,7 @@ public function verifySignature(Request $request, string $serviceKey): bool $parts = []; - if($headerSignature !== null ) { + if ($headerSignature !== null) { parse_str(str_replace([';', '='], ['&', '='], $headerSignature), $parts); } diff --git a/src/Resolver/SignatureResolverInterface.php b/src/Resolver/SignatureResolverInterface.php index 8a98726..1722aee 100644 --- a/src/Resolver/SignatureResolverInterface.php +++ b/src/Resolver/SignatureResolverInterface.php @@ -6,7 +6,6 @@ * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career */ - declare(strict_types=1); namespace BitBag\SyliusImojePlugin\Resolver; From 20f4d74ea26ca894526014fffb01c379a257ff84 Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Mon, 15 Apr 2024 12:38:20 +0200 Subject: [PATCH 07/18] fix githubaction --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f382043..68d16e8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,11 +21,11 @@ jobs: strategy: fail-fast: false matrix: - php: [ "8.1" ] + php: [ "8.0", "8.1" ] symfony: [ "5.4.*", "^6.0" ] sylius: [ "^1.12" ] - node: [ "14.x" ] - mysql: [ "8.0" ] + node: [ "14.x", "16.x", "18.x" ] + mysql: ["5.7", "8.0"] env: APP_ENV: test From 9007c52dcf59de2abfd7108d25ac219229218579 Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Mon, 15 Apr 2024 12:42:11 +0200 Subject: [PATCH 08/18] rollback githubaction --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 68d16e8..f382043 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,11 +21,11 @@ jobs: strategy: fail-fast: false matrix: - php: [ "8.0", "8.1" ] + php: [ "8.1" ] symfony: [ "5.4.*", "^6.0" ] sylius: [ "^1.12" ] - node: [ "14.x", "16.x", "18.x" ] - mysql: ["5.7", "8.0"] + node: [ "14.x" ] + mysql: [ "8.0" ] env: APP_ENV: test From 31d5f2b1fb8e9afe623f82a41503fa8de960a48b Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Tue, 16 Apr 2024 08:57:07 +0200 Subject: [PATCH 09/18] symfony 5.4 fixes --- src/Action/NotifyAction.php | 4 +++- src/Form/Type/ImojeGatewayConfigurationType.php | 2 +- src/Provider/PaymentTokenProvider.php | 1 + tests/Application/.env | 2 ++ tests/Application/var/.gitignore | 0 5 files changed, 7 insertions(+), 2 deletions(-) delete mode 100644 tests/Application/var/.gitignore diff --git a/src/Action/NotifyAction.php b/src/Action/NotifyAction.php index dd494d9..2f1cb1a 100644 --- a/src/Action/NotifyAction.php +++ b/src/Action/NotifyAction.php @@ -39,7 +39,9 @@ public function execute($request): void { RequestNotSupportedException::assertSupports($this, $request); - $notificationData = json_decode($this->request->getContent(), true); + /** @var string $content */ + $content = $this->request->getContent(); + $notificationData = json_decode($content, true); $transactionData = $notificationData['transaction']; $model = $request->getModel(); diff --git a/src/Form/Type/ImojeGatewayConfigurationType.php b/src/Form/Type/ImojeGatewayConfigurationType.php index f8c3b9b..c8b5636 100644 --- a/src/Form/Type/ImojeGatewayConfigurationType.php +++ b/src/Form/Type/ImojeGatewayConfigurationType.php @@ -19,7 +19,7 @@ final class ImojeGatewayConfigurationType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add( diff --git a/src/Provider/PaymentTokenProvider.php b/src/Provider/PaymentTokenProvider.php index 4b938e1..4670c6b 100644 --- a/src/Provider/PaymentTokenProvider.php +++ b/src/Provider/PaymentTokenProvider.php @@ -26,6 +26,7 @@ public function __construct( public function provideToken(Request $request): ?PaymentSecurityTokenInterface { + /** @var string $content */ $content = $request->getContent(); $content = json_decode($content, true); diff --git a/tests/Application/.env b/tests/Application/.env index c78ac22..f4085ce 100644 --- a/tests/Application/.env +++ b/tests/Application/.env @@ -31,3 +31,5 @@ SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN=doctrine://default?queue_name=main_fa 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 ###< symfony/messenger ### + +MESSENGER_TRANSPORT_DSN=doctrine://default diff --git a/tests/Application/var/.gitignore b/tests/Application/var/.gitignore deleted file mode 100644 index e69de29..0000000 From e54175d6c09ab04ebce23cc0ade60072a550ff47 Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Tue, 16 Apr 2024 09:06:05 +0200 Subject: [PATCH 10/18] OP-263 symfony 5.4 fixes --- composer.json | 1 + tests/Application/composer.json | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3083318..ec2364e 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ "license": "MIT", "require": { "php": "^8.1", + "doctrine/annotations": "^1.14", "sylius/sylius": "^1.12", "sylius/mailer-bundle": "^1.8 || ^2.0@beta", "symfony/webpack-encore-bundle": "^1.15" diff --git a/tests/Application/composer.json b/tests/Application/composer.json index 326735f..eb3d48e 100644 --- a/tests/Application/composer.json +++ b/tests/Application/composer.json @@ -1,5 +1,8 @@ { "name": "sylius/plugin-skeleton-test-application", "description": "Sylius application for plugin testing purposes (composer.json needed for project dir resolving)", - "license": "MIT" + "license": "MIT", + "require": { + "doctrine/annotations": "^1.14" + } } From 9d6075e05ccb167e49735ad50948474a29911251 Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Tue, 16 Apr 2024 09:50:28 +0200 Subject: [PATCH 11/18] OP-263 remove idea --- .gitignore | 1 + .idea/.gitignore | 8 - .idea/SyliusImojePaywallPlugin.iml | 262 ---------------- .idea/codeception.xml | 12 - .idea/inspectionProfiles/Project_Default.xml | 8 - .idea/modules.xml | 8 - .idea/php-test-framework.xml | 21 -- .idea/php.xml | 303 ------------------- .idea/phpspec.xml | 10 - .idea/phpunit.xml | 10 - .idea/vcs.xml | 6 - 11 files changed, 1 insertion(+), 648 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/SyliusImojePaywallPlugin.iml delete mode 100644 .idea/codeception.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/php-test-framework.xml delete mode 100644 .idea/php.xml delete mode 100644 .idea/phpspec.xml delete mode 100644 .idea/phpunit.xml delete mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore index 986c41a..0584aeb 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ # Symfony CLI https://symfony.com/doc/current/setup/symfony_server.html#different-php-settings-per-project /.php-version /php.ini +.idea/ ###> friendsofphp/php-cs-fixer ### /.php-cs-fixer.php diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/SyliusImojePaywallPlugin.iml b/.idea/SyliusImojePaywallPlugin.iml deleted file mode 100644 index 1556cdb..0000000 --- a/.idea/SyliusImojePaywallPlugin.iml +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeception.xml b/.idea/codeception.xml deleted file mode 100644 index 330f2dd..0000000 --- a/.idea/codeception.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 9a737d3..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 54e6421..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/php-test-framework.xml b/.idea/php-test-framework.xml deleted file mode 100644 index 0e401b0..0000000 --- a/.idea/php-test-framework.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml deleted file mode 100644 index f043b45..0000000 --- a/.idea/php.xml +++ /dev/null @@ -1,303 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/phpspec.xml b/.idea/phpspec.xml deleted file mode 100644 index 33107fd..0000000 --- a/.idea/phpspec.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/phpunit.xml b/.idea/phpunit.xml deleted file mode 100644 index 4f8104c..0000000 --- a/.idea/phpunit.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From eaa042a98963a38163274bca2d038325efcd5c03 Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Tue, 16 Apr 2024 14:38:19 +0200 Subject: [PATCH 12/18] OP-263 Refactoring code - fix specs, src, ecs --- ecs.php | 2 - phpstan.neon | 1 + spec/Action/CaptureActionSpec.php | 20 ++++----- spec/Action/ConvertPaymentActionSpec.php | 32 ++++++++------ spec/Action/NotifyActionSpec.php | 40 +++++++---------- spec/Action/StatusActionSpec.php | 33 ++++++++------ spec/ImojeGatewayFactorySpec.php | 8 ++-- spec/Provider/PaymentTokenProviderSpec.php | 50 ++++++---------------- spec/Resolver/SignatureResolverSpec.php | 41 ++++++++---------- src/Action/NotifyAction.php | 2 +- src/Controller/NotifyController.php | 2 +- src/Provider/PaymentTokenProvider.php | 7 ++- src/Resolver/SignatureResolver.php | 11 ++--- 13 files changed, 110 insertions(+), 139 deletions(-) diff --git a/ecs.php b/ecs.php index 16db5bc..3cf43de 100644 --- a/ecs.php +++ b/ecs.php @@ -12,8 +12,6 @@ __DIR__ . '/ecs.php', ]); - putenv('ALLOW_BITBAG_OS_HEADER=0'); - $ecsConfig->import('vendor/sylius-labs/coding-standard/ecs.php'); $ecsConfig->skip([ diff --git a/phpstan.neon b/phpstan.neon index e278f59..3256831 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -17,3 +17,4 @@ parameters: ignoreErrors: - '/Parameter #1 \$configuration of method Symfony\\Component\\DependencyInjection\\Extension\\Extension::processConfiguration\(\) expects Symfony\\Component\\Config\\Definition\\ConfigurationInterface, Symfony\\Component\\Config\\Definition\\ConfigurationInterface\|null given\./' + - '#Property .+::\$requestStack is never read, only written\.#' diff --git a/spec/Action/CaptureActionSpec.php b/spec/Action/CaptureActionSpec.php index 6254916..821daaf 100644 --- a/spec/Action/CaptureActionSpec.php +++ b/spec/Action/CaptureActionSpec.php @@ -24,16 +24,17 @@ use Sylius\Component\Customer\Model\CustomerInterface; use Symfony\Component\HttpFoundation\Request; -class CaptureActionSpec extends ObjectBehavior +final class CaptureActionSpec extends ObjectBehavior { public function let( SignatureResolverInterface $signatureResolver, ): void { $this->beConstructedWith($signatureResolver); } + public function it_should_return_true_when_request_and_model_is_valid( Capture $request, - ArrayObject $arrayObject + ArrayObject $arrayObject, ): void { $request->getModel()->willReturn($arrayObject); $this->supports($request)->shouldReturn(true); @@ -45,6 +46,7 @@ public function it_should_return_false_when_model_is_invalid( $request->getModel()->willReturn(null); $this->supports($request)->shouldReturn(false); } + public function it_should_return_false_when_request_invalid( Request $request, ): void { @@ -61,8 +63,7 @@ public function it_executes_correctly_with_valid_request( ImojeApi $apiClass, SignatureResolverInterface $signatureResolver, ): void { - - $data = ['statusImoje' => ImojeApiInterface::NEW_STATUS, 'paymentId' => 123, 'tokenHash'=>'1234sdcsdfxz']; + $data = ['statusImoje' => ImojeApiInterface::NEW_STATUS, 'paymentId' => 123, 'tokenHash' => '1234sdcsdfxz']; $request->getModel()->willReturn(new ArrayObject($data)); $request->getToken()->willReturn('1234sdcsdfxz'); @@ -78,7 +79,6 @@ public function it_executes_correctly_with_valid_request( $order->getBillingAddress()->willReturn($address); $order->getCustomer()->willReturn($customer); - $apiClass->getApiUrl()->willReturn('http://example.com/'); $apiClass->getServiceId()->willReturn('1'); @@ -100,15 +100,15 @@ public function it_executes_correctly_with_valid_request( 'customerFirstName' => 'John Doe', 'customerLastName' => 'Smith', 'urlReturn' => 'http://example.com/', - 'customerEmail' => 'john@doe.com' + 'customerEmail' => 'john@doe.com', ]; - $signatureResolver->createSignature($orderData,'1234sdcsdfxz') - ->willReturn('signature'); + $signatureResolver->createSignature($orderData, '1234sdcsdfxz') + ->willReturn('signature'); - $request->setModel(new ArrayObject($data))->shouldBeCalled(); - $this->setApi($apiClass); + $request->setModel(new ArrayObject($data))->shouldBeCalled(); + $this->setApi($apiClass); $this->shouldThrow(HttpPostRedirect::class) ->during('execute', [$request]); } diff --git a/spec/Action/ConvertPaymentActionSpec.php b/spec/Action/ConvertPaymentActionSpec.php index 5534131..1883e8b 100644 --- a/spec/Action/ConvertPaymentActionSpec.php +++ b/spec/Action/ConvertPaymentActionSpec.php @@ -17,29 +17,32 @@ use PhpSpec\ObjectBehavior; use Symfony\Component\HttpFoundation\Request; -class ConvertPaymentActionSpec extends ObjectBehavior +final class ConvertPaymentActionSpec extends ObjectBehavior { - public function it_is_initializable(): void{ + public function it_is_initializable(): void + { $this->shouldHaveType(ConvertPaymentAction::class); } - function it_implements_imoje_gateway_factory_interface(): void { + function it_implements_imoje_gateway_factory_interface(): void + { $this->shouldHaveType(ActionInterface::class); } public function it_sets_result_from_payment_details_with_non_empty_details( Convert $request, - PaymentInterface $payment - ): void{ + PaymentInterface $payment, + ): void { $request->getSource()->willReturn($payment); $payment->getDetails()->willReturn(['field' => '123']); $request->setResult(['field' => '123'])->shouldBeCalled(); $this->execute($request); } + public function it_sets_empty_result_when_payment_details_are_empty( Convert $request, - PaymentInterface $payment + PaymentInterface $payment, ): void { $payment->getDetails()->willReturn([]); $request->getSource()->willReturn($payment); @@ -49,8 +52,8 @@ public function it_sets_empty_result_when_payment_details_are_empty( } public function it_sets_result_when_payment_details_contain_null( - Convert $request, - PaymentInterface $payment + Convert $request, + PaymentInterface $payment, ): void { $payment->getDetails()->willReturn(['key' => null]); $request->getSource()->willReturn($payment); @@ -58,9 +61,10 @@ public function it_sets_result_when_payment_details_contain_null( $this->execute($request); } + public function it_should_return_true_when_getTo_and_source_is_valid( Convert $request, - PaymentInterface $payment + PaymentInterface $payment, ): void { $request->getSource()->willReturn($payment); $request->getTo()->willReturn('array'); @@ -69,7 +73,7 @@ public function it_should_return_true_when_getTo_and_source_is_valid( } public function it_should_return_false_when_source_is_invalid( - Convert $request + Convert $request, ): void { $request->getSource()->willReturn(null); $request->getTo()->willReturn('array'); @@ -78,22 +82,24 @@ public function it_should_return_false_when_source_is_invalid( } public function it_should_return_false_when_getTo_is_invalid( - Convert $request, - PaymentInterface $payment + Convert $request, + PaymentInterface $payment, ): void { $request->getSource()->willReturn($payment); $request->getTo()->willReturn('object'); $this->supports($request)->shouldReturn(false); } + public function it_should_return_false_when_getTo_and_source_is_invalid( Convert $request, - ) : void { + ): void { $request->getSource()->willReturn(null); $request->getTo()->willReturn('object'); $this->supports($request)->shouldReturn(false); } + public function it_should_return_false_when_request_invalid( Request $request, ): void { diff --git a/spec/Action/NotifyActionSpec.php b/spec/Action/NotifyActionSpec.php index b685411..246c315 100644 --- a/spec/Action/NotifyActionSpec.php +++ b/spec/Action/NotifyActionSpec.php @@ -14,12 +14,11 @@ use BitBag\SyliusImojePlugin\Resolver\SignatureResolverInterface; use Payum\Core\Bridge\Spl\ArrayObject; use Payum\Core\Request\Notify; -use Symfony\Component\HttpFoundation\Request; use PhpSpec\ObjectBehavior; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; - -class NotifyActionSpec extends ObjectBehavior +final class NotifyActionSpec extends ObjectBehavior { public function let( RequestStack $requestStack, @@ -27,9 +26,10 @@ public function let( ): void { $this->beConstructedWith( $requestStack, - $signatureResolver + $signatureResolver, ); } + public function it_should_return_true_when_request_and_request_data_is_valid( Notify $request, ArrayObject $arrayObject, @@ -42,10 +42,8 @@ public function it_should_return_true_when_request_and_request_data_is_valid( $requestStack->getCurrentRequest() ->willReturn($httpRequest); $api->getServiceKey()->willReturn('1234sdcsdfxz'); - $signatureResolver->verifySignature($httpRequest, '1234sdcsdfxz') - ->willReturn(true) - ->shouldBeCalled(); + ->willReturn(true); $this->setApi($api); $this->supports($request)->shouldReturn(true); @@ -62,10 +60,8 @@ public function it_should_return_false_when_request_and_signature_are_invalid( $request->getModel()->willReturn($arrayObject); $requestStack->getCurrentRequest()->willReturn($httpRequest); $api->getServiceKey()->willReturn('1234sdcsdfxz'); - $signatureResolver->verifySignature($httpRequest, '1234sdcsdfxz') - ->willReturn(false) - ->shouldBeCalled(); + ->willReturn(false); $this->setApi($api); $this->supports($request)->shouldReturn(false); @@ -105,30 +101,24 @@ public function it_sets_model_status_from_notification_data( ): void { $requestStack->getCurrentRequest()->willReturn($httpRequest); $api->getServiceKey()->willReturn('1234sdcsdfxz'); - $signatureResolver->verifySignature($httpRequest, '1234sdcsdfxz') - ->willReturn(true) - ->shouldBeCalled(); - - $notificationData = ['transaction' => ['status' => 'new','paymentId' => 1, 'tokenHash'=>'1234sdcsdfxz']]; + ->willReturn(true); + $notificationData = ['transaction' => ['status' => 'new', 'paymentId' => 1, 'tokenHash' => '1234sdcsdfxz']]; $jsonNotificationData = json_encode($notificationData); $httpRequest->getContent()->willReturn($jsonNotificationData); - $request->getModel()->willReturn(new ArrayObject([ 'status' => 'new', 'paymentId' => 1, - 'tokenHash'=>'1234sdcsdfxz' + 'tokenHash' => '1234sdcsdfxz', ])); - - $request->setModel(new ArrayObject([ - 'status' => 'new', - 'paymentId' => 1, - 'tokenHash'=>'1234sdcsdfxz', - 'statusImoje' => 'new' - ]))->willReturn($arrayObject)->shouldBeCalled(); + $request->setModel(new ArrayObject([ + 'status' => 'new', + 'paymentId' => 1, + 'tokenHash' => '1234sdcsdfxz', + 'statusImoje' => 'new', + ]))->willReturn($arrayObject); $this->setApi($api); $this->execute($request); } - } diff --git a/spec/Action/StatusActionSpec.php b/spec/Action/StatusActionSpec.php index 8a57c66..0cf0f2d 100644 --- a/spec/Action/StatusActionSpec.php +++ b/spec/Action/StatusActionSpec.php @@ -10,6 +10,7 @@ namespace spec\BitBag\SyliusImojePlugin\Action; +use ArrayAccess; use BitBag\SyliusImojePlugin\Action\StatusAction; use BitBag\SyliusImojePlugin\Api\ImojeApiInterface; use Doctrine\Common\Collections\ArrayCollection; @@ -17,10 +18,9 @@ use Payum\Core\Exception\RequestNotSupportedException; use Payum\Core\Request\GetStatusInterface; use PhpSpec\ObjectBehavior; -use ArrayAccess; use Symfony\Component\HttpFoundation\Request; -class StatusActionSpec extends ObjectBehavior +final class StatusActionSpec extends ObjectBehavior { public function it_is_initializable(): void { @@ -38,6 +38,7 @@ public function it_should_return_new_status( $data = ['statusImoje' => ImojeApiInterface::NEW_STATUS, 'paymentId' => 1]; $request->getModel()->willReturn(new ArrayCollection($data)); + $request->markNew()->shouldBeCalled(); $this->execute($request); @@ -53,14 +54,16 @@ public function it_should_return_pending_status( $this->execute($request); } + public function it_should_return_cancelled_status( GetStatusInterface $request, ): void { - $data = ['statusImoje' => ImojeApiInterface::CANCELLED_STATUS, 'paymentId' => 1, 'tokenHash'=>'dfgdsgxcvxcerf234']; + $data = ['statusImoje' => ImojeApiInterface::CANCELLED_STATUS, 'paymentId' => 1, 'tokenHash' => 'dfgdsgxcvxcerf234']; $request->getModel()->willReturn(new ArrayCollection($data)); $request->markCanceled()->shouldBeCalled(); $data['tokenHash'] = ''; + $request->setModel(new ArrayCollection($data))->shouldBeCalled(); $this->execute($request); @@ -69,11 +72,11 @@ public function it_should_return_cancelled_status( public function it_should_return_rejected_status( GetStatusInterface $request, ): void { - $data = ['statusImoje' => ImojeApiInterface::REJECTED_STATUS, 'paymentId' => 1, 'tokenHash'=>'dfgdsgxcvxcerf234']; - + $data = ['statusImoje' => ImojeApiInterface::REJECTED_STATUS, 'paymentId' => 1, 'tokenHash' => 'dfgdsgxcvxcerf234']; $request->getModel()->willReturn(new ArrayCollection($data)); $request->markFailed()->shouldBeCalled(); $data['tokenHash'] = ''; + $request->setModel(new ArrayCollection($data))->shouldBeCalled(); $this->execute($request); @@ -82,9 +85,9 @@ public function it_should_return_rejected_status( public function it_should_return_settled_status( GetStatusInterface $request, ): void { - $data = ['statusImoje' => ImojeApiInterface::SETTLED_STATUS, 'paymentId' => 1, 'tokenHash'=>'dfgdsgxcvxcerf234']; - + $data = ['statusImoje' => ImojeApiInterface::SETTLED_STATUS, 'paymentId' => 1, 'tokenHash' => 'dfgdsgxcvxcerf234']; $request->getModel()->willReturn(new ArrayCollection($data)); + $request->markCaptured()->shouldBeCalled(); $this->execute($request); @@ -93,38 +96,40 @@ public function it_should_return_settled_status( public function it_should_return_unknown_status( GetStatusInterface $request, ): void { - $data = ['statusImoje' => 'test', 'paymentId' => 1, 'tokenHash'=>'dfgdsgxcvxcerf234']; - + $data = ['statusImoje' => 'test', 'paymentId' => 1, 'tokenHash' => 'dfgdsgxcvxcerf234']; $request->getModel()->willReturn(new ArrayCollection($data)); + $request->markUnknown()->shouldBeCalled(); $this->execute($request); } function it_throws_exception_if_request_not_supported( - GetStatusInterface $request + GetStatusInterface $request, ): void { $this->shouldThrow(RequestNotSupportedException::class)->during('execute', [$request]); } function it_returns_true_if_request_is_valid( GetStatusInterface $request, - ArrayAccess $model + ArrayAccess $model, ): void { $request->getModel()->willReturn($model); + $this->supports($request)->shouldBe(true); } function it_returns_false_if_request_model_is_empty( - GetStatusInterface $request + GetStatusInterface $request, ): void { $request->getModel()->willReturn(null); + $this->supports($request)->shouldBe(false); } + function it_returns_false_if_request_class_not_instanceof_GetStatusInterface( - Request $request + Request $request, ): void { $this->supports($request)->shouldBe(false); } - } diff --git a/spec/ImojeGatewayFactorySpec.php b/spec/ImojeGatewayFactorySpec.php index de4f133..0a1c73d 100644 --- a/spec/ImojeGatewayFactorySpec.php +++ b/spec/ImojeGatewayFactorySpec.php @@ -14,17 +14,15 @@ use Payum\Core\GatewayFactoryInterface; use PhpSpec\ObjectBehavior; -class ImojeGatewayFactorySpec extends ObjectBehavior +final class ImojeGatewayFactorySpec extends ObjectBehavior { public function it_is_initializable(): void { $this->shouldHaveType(ImojeGatewayFactory::class); } - function it_implements_imoje_gateway_factory_interface(): void{ + function it_implements_imoje_gateway_factory_interface(): void + { $this->shouldHaveType(GatewayFactoryInterface::class); } - - } - diff --git a/spec/Provider/PaymentTokenProviderSpec.php b/spec/Provider/PaymentTokenProviderSpec.php index 36983b1..f8b2dd7 100644 --- a/spec/Provider/PaymentTokenProviderSpec.php +++ b/spec/Provider/PaymentTokenProviderSpec.php @@ -19,7 +19,7 @@ use Sylius\Component\Resource\Repository\RepositoryInterface; use Symfony\Component\HttpFoundation\Request; -class PaymentTokenProviderSpec extends ObjectBehavior +final class PaymentTokenProviderSpec extends ObjectBehavior { public function let( RepositoryInterface $orderRepository, @@ -48,30 +48,18 @@ public function it_should_return_token_correctly( 'transaction' => [ 'orderId' => $orderNumber, 'tokenHash' => $tokenHash, - ] + ], ]; - $request->getContent() - ->willReturn(json_encode($transactionData)); - - $orderRepository->findOneBy(['number' => $orderNumber]) - ->willReturn($order); - + $request->getContent()->willReturn(json_encode($transactionData)); + $orderRepository->findOneBy(['number' => $orderNumber])->willReturn($order); $order->getPayments() ->willReturn(new ArrayCollection([ - $payment->getWrappedObject() + $payment->getWrappedObject(), ])); - - $payment->getState() - ->willReturn(PaymentInterface::STATE_NEW); - - $payment->getDetails() - ->shouldBeCalled() - ->willReturn(['tokenHash' => $tokenHash]); - - $paymentTokenRepository->findOneBy(['hash' => $tokenHash]) - ->willReturn($token) - ->shouldBeCalled(); + $payment->getState()->willReturn(PaymentInterface::STATE_NEW); + $payment->getDetails()->willReturn(['tokenHash' => $tokenHash]); + $paymentTokenRepository->findOneBy(['hash' => $tokenHash])->willReturn($token); $this->provideToken($request)->shouldReturn($token); } @@ -84,34 +72,22 @@ public function it_should_return_null_if_paymentTokenRepository_is_not_called( ): void { $orderNumber = 500; $tokenHash = '3423423453fsxzc'; - $transactionData = [ 'transaction' => [ 'orderId' => $orderNumber, 'tokenHash' => $tokenHash, - ] + ], ]; - - $request->getContent() - ->willReturn(json_encode($transactionData)); - + $request->getContent()->willReturn(json_encode($transactionData)); $orderRepository->findOneBy(['number' => $orderNumber]) ->willReturn($order); - $order->getPayments() ->willReturn(new ArrayCollection([ - $payment->getWrappedObject() + $payment->getWrappedObject(), ])); - - $payment->getState() - ->willReturn(PaymentInterface::STATE_CANCELLED); - - $payment->getDetails() - ->shouldBeCalled() - ->willReturn(['tokenHash' => $tokenHash]); - + $payment->getState()->willReturn(PaymentInterface::STATE_CANCELLED); + $payment->getDetails()->willReturn(['tokenHash' => $tokenHash]); $this->provideToken($request)->shouldReturn(null); - } } diff --git a/spec/Resolver/SignatureResolverSpec.php b/spec/Resolver/SignatureResolverSpec.php index c6a5226..02ad24c 100644 --- a/spec/Resolver/SignatureResolverSpec.php +++ b/spec/Resolver/SignatureResolverSpec.php @@ -1,13 +1,15 @@ createSignature($fields, $serviceKey) - ->shouldReturn($expectedHash); + $this->createSignature($fields, $serviceKey)->shouldReturn($expectedHash); } + public function it_should_return_hash_with_service_key_only_when_fields_are_empty(): void { $fields = []; @@ -44,55 +46,50 @@ public function it_should_return_hash_without_service_key_when_service_key_is_em ]; $serviceKey = ''; $expectedDataString = 'field1=value1&field2=value2'; + $expectedHash = hash(ImojeApiInterface::HASHING_ALGORITHM, $expectedDataString) . ';' . ImojeApiInterface::HASHING_ALGORITHM; - $expectedHash = hash(ImojeApiInterface::HASHING_ALGORITHM, $expectedDataString ) . ';' . ImojeApiInterface::HASHING_ALGORITHM; - - $this->createSignature($fields, $serviceKey) - ->shouldReturn($expectedHash); + $this->createSignature($fields, $serviceKey)->shouldReturn($expectedHash); } public function it_should_return_true_if_signatures_match( - Request $request + Request $request, ): void { $serviceKey = 'adasvcx3412'; $body = 'test.jpg'; - $exampleHash = hash('sha256',sprintf('test.jpg%s',$serviceKey)); - $headerSignature = sprintf('alg=sha256;signature=%s',$exampleHash); - + $exampleHash = hash('sha256', sprintf('test.jpg%s', $serviceKey)); + $headerSignature = sprintf('alg=sha256;signature=%s', $exampleHash); $request->getContent()->willReturn($body); + $request->headers = new \Symfony\Component\HttpFoundation\HeaderBag(['X-Imoje-Signature' => $headerSignature]); $this->verifySignature($request, $serviceKey)->shouldBe(true); - } public function it_should_return_false_if_signatures_not_match( - Request $request + Request $request, ): void { $serviceKey = 'adasvcx3412'; $body = 'test2.jpg'; - $exampleHash = hash('sha256',sprintf('test.jpg%s',$serviceKey)); - $headerSignature = sprintf('alg=sha256;signature=%s',$exampleHash); - + $exampleHash = hash('sha256', sprintf('test.jpg%s', $serviceKey)); + $headerSignature = sprintf('alg=sha256;signature=%s', $exampleHash); $request->getContent()->willReturn($body); + $request->headers = new \Symfony\Component\HttpFoundation\HeaderBag(['X-Imoje-Signature' => $headerSignature]); $this->verifySignature($request, $serviceKey)->shouldBe(false); - } public function it_should_return_false_if_content_is_empty( - Request $request + Request $request, ): void { $serviceKey = ''; $body = ''; $exampleHash = ''; - $headerSignature = sprintf('alg=sha256;signature=%s',$exampleHash); - + $headerSignature = sprintf('alg=sha256;signature=%s', $exampleHash); $request->getContent()->willReturn($body); + $request->headers = new \Symfony\Component\HttpFoundation\HeaderBag(['X-Imoje-Signature' => $headerSignature]); $this->verifySignature($request, $serviceKey)->shouldBe(false); - } } diff --git a/src/Action/NotifyAction.php b/src/Action/NotifyAction.php index 2f1cb1a..85e02c5 100644 --- a/src/Action/NotifyAction.php +++ b/src/Action/NotifyAction.php @@ -28,7 +28,7 @@ final class NotifyAction implements ActionInterface, ApiAwareInterface private Request $request; public function __construct( - protected RequestStack $requestStack, + private readonly RequestStack $requestStack, private readonly SignatureResolverInterface $signatureResolver, ) { $this->request = $requestStack->getCurrentRequest() ?? new Request(); diff --git a/src/Controller/NotifyController.php b/src/Controller/NotifyController.php index 6a4f3fc..600c04e 100644 --- a/src/Controller/NotifyController.php +++ b/src/Controller/NotifyController.php @@ -29,7 +29,7 @@ public function __construct( public function verifyImojeNotification(Request $request): Response { - if ($request->getContent() === '') { + if ($request->getContent() !== '') { return new Response('', Response::HTTP_NO_CONTENT); } diff --git a/src/Provider/PaymentTokenProvider.php b/src/Provider/PaymentTokenProvider.php index 4670c6b..bbdde64 100644 --- a/src/Provider/PaymentTokenProvider.php +++ b/src/Provider/PaymentTokenProvider.php @@ -10,6 +10,7 @@ namespace BitBag\SyliusImojePlugin\Provider; +use Ramsey\Collection\Collection; use Sylius\Bundle\PayumBundle\Model\PaymentSecurityTokenInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\PaymentInterface; @@ -32,12 +33,10 @@ public function provideToken(Request $request): ?PaymentSecurityTokenInterface $transactionData = $content['transaction']; + /** @var OrderInterface $order */ $order = $this->getOrder($transactionData); - if ($order == null) { - return null; - } - + /** @var Collection $payments */ $payments = $order->getPayments(); foreach ($payments as $payment) { diff --git a/src/Resolver/SignatureResolver.php b/src/Resolver/SignatureResolver.php index 65580d0..1e03eee 100644 --- a/src/Resolver/SignatureResolver.php +++ b/src/Resolver/SignatureResolver.php @@ -12,6 +12,7 @@ use BitBag\SyliusImojePlugin\Api\ImojeApiInterface; use Symfony\Component\HttpFoundation\Request; +use Webmozart\Assert\Assert; final class SignatureResolver implements SignatureResolverInterface { @@ -35,17 +36,17 @@ public function createSignature(array $fields, string $serviceKey): string public function verifySignature(Request $request, string $serviceKey): bool { + /** @var string $headerSignature */ $headerSignature = $request->headers->get('X-Imoje-Signature'); $body = $request->getContent(); $parts = []; + parse_str(str_replace([';', '='], ['&', '='], $headerSignature), $parts); - if ($headerSignature !== null) { - parse_str(str_replace([';', '='], ['&', '='], $headerSignature), $parts); - } + Assert::keyExists($parts, 'alg'); + Assert::string($parts['alg']); - $algo = is_string($parts['alg']) ? $parts['alg'] : 'sha256'; - $ownSignature = hash($algo, $body . $serviceKey); + $ownSignature = hash($parts['alg'], $body . $serviceKey); return $ownSignature === $parts['signature']; } From b82eb4b1020ca279fc9ba4ba84cc6b15d10e803e Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Wed, 17 Apr 2024 09:08:46 +0200 Subject: [PATCH 13/18] OP-263 Refactoring code - fix specs, controller, gitignore --- .gitignore | 1 - .php-cs-fixer.dist.php | 13 ------------- spec/Action/CaptureActionSpec.php | 3 ++- src/Controller/NotifyController.php | 16 ++++++++-------- 4 files changed, 10 insertions(+), 23 deletions(-) delete mode 100644 .php-cs-fixer.dist.php diff --git a/.gitignore b/.gitignore index 0584aeb..986c41a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ # Symfony CLI https://symfony.com/doc/current/setup/symfony_server.html#different-php-settings-per-project /.php-version /php.ini -.idea/ ###> friendsofphp/php-cs-fixer ### /.php-cs-fixer.php diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php deleted file mode 100644 index 3788194..0000000 --- a/.php-cs-fixer.dist.php +++ /dev/null @@ -1,13 +0,0 @@ -in(__DIR__) - ->exclude('var') -; - -return (new PhpCsFixer\Config()) - ->setRules([ - '@Symfony' => true, - ]) - ->setFinder($finder) -; diff --git a/spec/Action/CaptureActionSpec.php b/spec/Action/CaptureActionSpec.php index 821daaf..4b49ae1 100644 --- a/spec/Action/CaptureActionSpec.php +++ b/spec/Action/CaptureActionSpec.php @@ -37,6 +37,7 @@ public function it_should_return_true_when_request_and_model_is_valid( ArrayObject $arrayObject, ): void { $request->getModel()->willReturn($arrayObject); + $this->supports($request)->shouldReturn(true); } @@ -47,7 +48,7 @@ public function it_should_return_false_when_model_is_invalid( $this->supports($request)->shouldReturn(false); } - public function it_should_return_false_when_request_invalid( + public function it_should_return_false_when_request_is_not_a_capture_instance( Request $request, ): void { $this->supports($request)->shouldReturn(false); diff --git a/src/Controller/NotifyController.php b/src/Controller/NotifyController.php index 600c04e..550c837 100644 --- a/src/Controller/NotifyController.php +++ b/src/Controller/NotifyController.php @@ -29,22 +29,22 @@ public function __construct( public function verifyImojeNotification(Request $request): Response { - if ($request->getContent() !== '') { + if ('' !== $request->getContent()) { return new Response('', Response::HTTP_NO_CONTENT); } $paymentToken = $this->paymentTokenProvider->provideToken($request); - if (null !== $paymentToken) { - $notifyToken = $this->payum->getHttpRequestVerifier()->verify($this->createRequestWithToken($request, $paymentToken)); - $gateway = $this->payum->getGateway($notifyToken->getGatewayName()); + if (null === $paymentToken) { + throw new NotFoundHttpException('Payment token not found'); + } - $gateway->execute(new Notify($notifyToken)); + $notifyToken = $this->payum->getHttpRequestVerifier()->verify($this->createRequestWithToken($request, $paymentToken)); + $gateway = $this->payum->getGateway($notifyToken->getGatewayName()); - return new JsonResponse(['status' => 'ok']); - } + $gateway->execute(new Notify($notifyToken)); - throw new NotFoundHttpException('Payment token not found'); + return new JsonResponse(['status' => 'ok']); } private function createRequestWithToken( From 4b8529e1ad3aa025c13a59a240163667391f268a Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Wed, 17 Apr 2024 09:14:42 +0200 Subject: [PATCH 14/18] OP-263 Refactoring code - fix specs, controller, gitignore --- spec/Action/CaptureActionSpec.php | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/Action/CaptureActionSpec.php b/spec/Action/CaptureActionSpec.php index 4b49ae1..b33bf3e 100644 --- a/spec/Action/CaptureActionSpec.php +++ b/spec/Action/CaptureActionSpec.php @@ -45,6 +45,7 @@ public function it_should_return_false_when_model_is_invalid( Capture $request, ): void { $request->getModel()->willReturn(null); + $this->supports($request)->shouldReturn(false); } From 71f2858ed09416d8bd6beb4cd56a1eadc11bbcc8 Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Fri, 10 May 2024 14:00:06 +0200 Subject: [PATCH 15/18] OP-263 Remove instantiation of Request --- src/Action/NotifyAction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Action/NotifyAction.php b/src/Action/NotifyAction.php index 85e02c5..2568673 100644 --- a/src/Action/NotifyAction.php +++ b/src/Action/NotifyAction.php @@ -31,7 +31,7 @@ public function __construct( private readonly RequestStack $requestStack, private readonly SignatureResolverInterface $signatureResolver, ) { - $this->request = $requestStack->getCurrentRequest() ?? new Request(); + $this->request = $requestStack->getCurrentRequest(); $this->apiClass = ImojeApi::class; } From ce666a22258869b8073028dcc62d7fce804321a0 Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Fri, 10 May 2024 14:26:59 +0200 Subject: [PATCH 16/18] OP-263 Added a condition for StateMachineAbstractionBundle in bundles configuration --- tests/Application/config/bundles.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/Application/config/bundles.php b/tests/Application/config/bundles.php index a5c1bb5..94bd806 100644 --- a/tests/Application/config/bundles.php +++ b/tests/Application/config/bundles.php @@ -1,6 +1,8 @@ ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], @@ -59,3 +61,9 @@ Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], League\FlysystemBundle\FlysystemBundle::class => ['all' => true], ]; + +if ( defined(SyliusCoreBundle::class.'::VERSION_ID') && SyliusCoreBundle::VERSION_ID >= '11300') { + $bundles[Sylius\Abstraction\StateMachine\SyliusStateMachineAbstractionBundle::class] = ['all' => true]; +} + +return $bundles; From 5fc1c45e3561d92bab12893baca1bf20046e56cb Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Fri, 10 May 2024 14:59:27 +0200 Subject: [PATCH 17/18] OP-263 OP-263 Added fix for PHPStan bug --- src/Action/NotifyAction.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Action/NotifyAction.php b/src/Action/NotifyAction.php index 2568673..c5afce2 100644 --- a/src/Action/NotifyAction.php +++ b/src/Action/NotifyAction.php @@ -25,7 +25,7 @@ final class NotifyAction implements ActionInterface, ApiAwareInterface { use ApiAwareTrait; - private Request $request; + private ?Request $request; public function __construct( private readonly RequestStack $requestStack, @@ -39,6 +39,10 @@ public function execute($request): void { RequestNotSupportedException::assertSupports($this, $request); + if(null == $this->request){ + throw new \Exception('Request is empty'); + } + /** @var string $content */ $content = $this->request->getContent(); $notificationData = json_decode($content, true); @@ -52,6 +56,9 @@ public function execute($request): void public function supports($request): bool { + if(null == $this->request){ + return false; + } return $request instanceof Notify && $request->getModel() instanceof ArrayObject && From 98418ee57aec27a8a8275b888f492c7c832f17c9 Mon Sep 17 00:00:00 2001 From: Szymon Kostrubiec Date: Fri, 10 May 2024 14:59:49 +0200 Subject: [PATCH 18/18] OP-263 OP-263 Added fix for PHPStan bug --- src/Action/NotifyAction.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Action/NotifyAction.php b/src/Action/NotifyAction.php index c5afce2..294c81e 100644 --- a/src/Action/NotifyAction.php +++ b/src/Action/NotifyAction.php @@ -39,7 +39,7 @@ public function execute($request): void { RequestNotSupportedException::assertSupports($this, $request); - if(null == $this->request){ + if (null == $this->request) { throw new \Exception('Request is empty'); } @@ -56,9 +56,10 @@ public function execute($request): void public function supports($request): bool { - if(null == $this->request){ - return false; + if (null == $this->request) { + return false; } + return $request instanceof Notify && $request->getModel() instanceof ArrayObject &&