From ff2a6ad64a217b526643f5ffcce70b1b48e243cf Mon Sep 17 00:00:00 2001 From: David Lobato Date: Thu, 4 Apr 2019 18:46:02 +0100 Subject: [PATCH 01/12] Implemented order available payment methods and order update payment Implemented validator and tests Update to symfony messenger Use tokenValue from fixture Revert small changes on non related order fixtures Check order state on UpdatePaymentMethodHandler Assert payment is in new state --- doc/swagger.yml | 63 ++++++- .../Command/Order/UpdatePaymentMethodSpec.php | 31 ++++ .../Order/PlacedOrderViewFactorySpec.php | 3 + .../Order/UpdatePaymentMethodHandlerSpec.php | 168 ++++++++++++++++++ .../Order/OrderExistsValidatorSpec.php | 63 +++++++ src/Command/Order/UpdatePaymentMethod.php | 39 ++++ .../Order/UpdatePaymentMethodAction.php | 59 ++++++ src/Factory/Order/PlacedOrderViewFactory.php | 1 + .../Order/UpdatePaymentMethodHandler.php | 52 ++++++ .../Order/UpdatePaymentMethodRequest.php | 32 ++++ src/Resources/config/routing/order.yml | 12 ++ .../config/services/actions/order.xml | 9 + .../config/services/handler/order.xml | 13 ++ .../config/services/validators/order.xml | 11 ++ .../order/UpdatePaymentMethodRequest.xml | 25 +++ src/Validator/Constraints/OrderExists.php | 23 +++ src/Validator/Order/OrderExistsValidator.php | 33 ++++ src/View/Order/PlacedOrderView.php | 3 + .../Order/OrderUpdatePaymentMethodApiTest.php | 61 +++++++ 19 files changed, 699 insertions(+), 2 deletions(-) create mode 100644 spec/Command/Order/UpdatePaymentMethodSpec.php create mode 100644 spec/Handler/Order/UpdatePaymentMethodHandlerSpec.php create mode 100644 spec/Validator/Order/OrderExistsValidatorSpec.php create mode 100644 src/Command/Order/UpdatePaymentMethod.php create mode 100644 src/Controller/Order/UpdatePaymentMethodAction.php create mode 100644 src/Handler/Order/UpdatePaymentMethodHandler.php create mode 100644 src/Request/Order/UpdatePaymentMethodRequest.php create mode 100644 src/Resources/config/services/handler/order.xml create mode 100644 src/Resources/config/services/validators/order.xml create mode 100644 src/Resources/config/validation/order/UpdatePaymentMethodRequest.xml create mode 100644 src/Validator/Constraints/OrderExists.php create mode 100644 src/Validator/Order/OrderExistsValidator.php create mode 100644 tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php diff --git a/doc/swagger.yml b/doc/swagger.yml index 835a85674..60603090c 100644 --- a/doc/swagger.yml +++ b/doc/swagger.yml @@ -394,7 +394,7 @@ paths: name: "content" required: true schema: - $ref: "#/definitions/CheckoutChoosePaymentMethodRequest" + $ref: "#/definitions/ChoosePaymentMethodRequest" responses: 204: description: "Payment method has been chosen." @@ -838,6 +838,51 @@ paths: security: - bearerAuth: [] + /orders/{token}/payment: + parameters: + - $ref: "#/parameters/CartToken" + get: + tags: + - "order" + summary: "Get available payment methods." + description: "This endpoint will show you available payment methods for an order." + operationId: "showAvailablePaymentMethods" + responses: + 200: + description: "Get available payment methods." + schema: + $ref: "#/definitions/AvailablePaymentMethods" + 400: + description: "Invalid input, validation failed." + schema: + $ref: "#/definitions/GeneralError" + /orders/{token}/payment/{id}: + parameters: + - $ref: "#/parameters/CartToken" + put: + tags: + - "order" + summary: "Choosing cart payment method." + description: "This endpoint will allow you to update an order payment method." + operationId: "updatePaymentMethod" + parameters: + - name: "id" + in: "path" + description: "Order number of payment for which payment method should be specified." + required: true + type: "string" + - in: "body" + name: "content" + required: true + schema: + $ref: "#/definitions/ChoosePaymentMethodRequest" + responses: + 204: + description: "Payment method has been chosen." + 400: + description: "Invalid input, validation failed." + schema: + $ref: "#/definitions/GeneralError" /me: get: tags: @@ -1116,7 +1161,7 @@ definitions: type: "string" description: "Code of chosen shipping method." example: "DHL" - CheckoutChoosePaymentMethodRequest: + ChoosePaymentMethodRequest: type: "object" description: "Body of request used to choose payment method." required: @@ -1808,6 +1853,20 @@ definitions: description: "Date the order was completed in ISO 8601 format." type: "string" format: "date-time" + paymentState: + description: "Current payment state of an order." + type: "string" + example: "awaiting_payment" + enum: + - "cart" + - "awaiting_payment" + - "partially_authorized" + - "authorized" + - "partially_paid" + - "cancelled" + - "paid" + - "partially_refunded" + - "refunded" items: type: "array" items: diff --git a/spec/Command/Order/UpdatePaymentMethodSpec.php b/spec/Command/Order/UpdatePaymentMethodSpec.php new file mode 100644 index 000000000..926040f50 --- /dev/null +++ b/spec/Command/Order/UpdatePaymentMethodSpec.php @@ -0,0 +1,31 @@ +beConstructedWith('ORDERTOKEN', 1, 'CASH_ON_DELIVERY_METHOD'); + } + + function it_has_order_token(): void + { + $this->orderToken()->shouldReturn('ORDERTOKEN'); + } + + function it_has_identifier_of_payment(): void + { + $this->paymentIdentifier()->shouldReturn(1); + } + + function it_has_payment_method_defined(): void + { + $this->paymentMethod()->shouldReturn('CASH_ON_DELIVERY_METHOD'); + } +} diff --git a/spec/Factory/Order/PlacedOrderViewFactorySpec.php b/spec/Factory/Order/PlacedOrderViewFactorySpec.php index 757f44058..5c617f133 100644 --- a/spec/Factory/Order/PlacedOrderViewFactorySpec.php +++ b/spec/Factory/Order/PlacedOrderViewFactorySpec.php @@ -11,6 +11,7 @@ use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\OrderItemInterface; use Sylius\Component\Core\OrderCheckoutStates; +use Sylius\Component\Core\OrderPaymentStates; use Sylius\ShopApiPlugin\Factory\AddressBook\AddressViewFactoryInterface; use Sylius\ShopApiPlugin\Factory\Cart\AdjustmentViewFactoryInterface; use Sylius\ShopApiPlugin\Factory\Cart\CartItemViewFactoryInterface; @@ -64,6 +65,7 @@ function it_creates_a_placed_order_view( $cart->getCurrencyCode()->willReturn('GBP'); $cart->getCheckoutState()->willReturn(OrderCheckoutStates::STATE_COMPLETED); $cart->getCheckoutCompletedAt()->willReturn(new \DateTime('2019-02-15T15:00:00+00:00')); + $cart->getPaymentState()->willReturn(OrderPaymentStates::STATE_AWAITING_PAYMENT); $cart->getTokenValue()->willReturn('ORDER_TOKEN'); $cart->getNumber()->willReturn('ORDER_NUMBER'); $cart->getShippingTotal()->willReturn(500); @@ -99,6 +101,7 @@ function it_creates_a_placed_order_view( $placedOrderView->locale = 'en_GB'; $placedOrderView->checkoutState = OrderCheckoutStates::STATE_COMPLETED; $placedOrderView->checkoutCompletedAt = '2019-02-15T15:00:00+00:00'; + $placedOrderView->paymentState = OrderPaymentStates::STATE_AWAITING_PAYMENT; $placedOrderView->items = [new ItemView()]; $placedOrderView->totals = new TotalsView(); diff --git a/spec/Handler/Order/UpdatePaymentMethodHandlerSpec.php b/spec/Handler/Order/UpdatePaymentMethodHandlerSpec.php new file mode 100644 index 000000000..f36b4d252 --- /dev/null +++ b/spec/Handler/Order/UpdatePaymentMethodHandlerSpec.php @@ -0,0 +1,168 @@ +beConstructedWith($orderRepository, $paymentMethodRepository); + } + + function it_assigns_chosen_payment_method_to_specified_payment( + OrderRepositoryInterface $orderRepository, + OrderInterface $order, + PaymentMethodRepositoryInterface $paymentMethodRepository, + PaymentMethodInterface $paymentMethod, + PaymentInterface $payment + ): void { + $orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($order); + $order->getState()->willReturn(OrderInterface::STATE_NEW); + $order->getPayments()->willReturn(new ArrayCollection([$payment->getWrappedObject()])); + $order->getPaymentState()->willReturn(OrderPaymentStates::STATE_AWAITING_PAYMENT); + $paymentMethodRepository->findOneBy(['code' => 'CASH_ON_DELIVERY_METHOD'])->willReturn($paymentMethod); + $payment->setMethod($paymentMethod)->shouldBeCalled(); + $payment->getState()->willReturn(PaymentInterface::STATE_NEW); + + $this(new UpdatePaymentMethod('ORDERTOKEN', 0, 'CASH_ON_DELIVERY_METHOD')); + } + + function it_throws_an_exception_if_order_with_given_token_has_not_been_found( + OrderRepositoryInterface $orderRepository, + PaymentInterface $payment + ): void { + $orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn(null); + $payment->setMethod(Argument::type(PaymentMethodInterface::class))->shouldNotBeCalled(); + + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('__invoke', [ + new UpdatePaymentMethod('ORDERTOKEN', 0, 'CASH_ON_DELIVERY_METHOD'), + ]) + ; + } + + function it_throws_an_exception_if_order_is_cart( + OrderRepositoryInterface $orderRepository, + OrderInterface $order, + PaymentMethodRepositoryInterface $paymentMethodRepository, + PaymentInterface $payment + ): void { + $orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($order); + $order->getState()->willReturn(OrderInterface::STATE_CART); + + $paymentMethodRepository->findOneBy(Argument::any())->shouldNotBeCalled(); + $payment->setMethod(Argument::type(PaymentMethodInterface::class))->shouldNotBeCalled(); + + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('__invoke', [ + new UpdatePaymentMethod('ORDERTOKEN', 0, 'CASH_ON_DELIVERY_METHOD'), + ]) + ; + } + + function it_throws_an_exception_if_order_cannot_have_payment_updated( + OrderRepositoryInterface $orderRepository, + OrderInterface $order, + PaymentMethodRepositoryInterface $paymentMethodRepository, + PaymentInterface $payment + ): void { + $orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($order); + $order->getState()->willReturn(OrderInterface::STATE_NEW); + $order->getPaymentState()->willReturn(OrderPaymentStates::STATE_PAID); + + $paymentMethodRepository->findOneBy(Argument::any())->shouldNotBeCalled(); + $payment->setMethod(Argument::type(PaymentMethodInterface::class))->shouldNotBeCalled(); + + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('__invoke', [ + new UpdatePaymentMethod('ORDERTOKEN', 0, 'CASH_ON_DELIVERY_METHOD'), + ]) + ; + } + + function it_throws_an_exception_if_payment_method_with_given_code_has_not_been_found( + OrderRepositoryInterface $orderRepository, + OrderInterface $order, + PaymentMethodRepositoryInterface $paymentMethodRepository, + PaymentInterface $payment + ): void { + $orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($order); + $order->getState()->willReturn(OrderInterface::STATE_NEW); + $order->getPaymentState()->willReturn(OrderPaymentStates::STATE_AWAITING_PAYMENT); + $paymentMethodRepository->findOneBy(['code' => 'CASH_ON_DELIVERY_METHOD'])->willReturn(null); + + $payment->setMethod(Argument::type(PaymentMethodInterface::class))->shouldNotBeCalled(); + + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('__invoke', [ + new UpdatePaymentMethod('ORDERTOKEN', 0, 'CASH_ON_DELIVERY_METHOD'), + ]) + ; + } + + function it_throws_an_exception_if_ordered_payment_has_not_been_found( + OrderRepositoryInterface $orderRepository, + OrderInterface $order, + PaymentMethodRepositoryInterface $paymentMethodRepository, + PaymentMethodInterface $paymentMethod, + PaymentInterface $payment + ): void { + $orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($order); + $order->getState()->willReturn(OrderInterface::STATE_NEW); + $order->getPaymentState()->willReturn(OrderPaymentStates::STATE_AWAITING_PAYMENT); + $paymentMethodRepository->findOneBy(['code' => 'CASH_ON_DELIVERY_METHOD'])->willReturn($paymentMethod); + $order->getPayments()->willReturn(new ArrayCollection([])); + + $payment->setMethod(Argument::type(PaymentMethodInterface::class))->shouldNotBeCalled(); + + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('__invoke', [ + new UpdatePaymentMethod('ORDERTOKEN', 0, 'CASH_ON_DELIVERY_METHOD'), + ]) + ; + } + + function it_throws_an_exception_if_ordered_payment_is_not_new( + OrderRepositoryInterface $orderRepository, + OrderInterface $order, + PaymentMethodRepositoryInterface $paymentMethodRepository, + PaymentMethodInterface $paymentMethod, + PaymentInterface $payment + ): void { + $orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($order); + $order->getState()->willReturn(OrderInterface::STATE_NEW); + $order->getPaymentState()->willReturn(OrderPaymentStates::STATE_AWAITING_PAYMENT); + $paymentMethodRepository->findOneBy(['code' => 'CASH_ON_DELIVERY_METHOD'])->willReturn($paymentMethod); + $order->getPayments()->willReturn(new ArrayCollection([$payment->getWrappedObject()])); + + $payment->getState()->willReturn(PaymentInterface::STATE_CART); + $payment->setMethod(Argument::type(PaymentMethodInterface::class))->shouldNotBeCalled(); + + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('__invoke', [ + new UpdatePaymentMethod('ORDERTOKEN', 0, 'CASH_ON_DELIVERY_METHOD'), + ]) + ; + } +} diff --git a/spec/Validator/Order/OrderExistsValidatorSpec.php b/spec/Validator/Order/OrderExistsValidatorSpec.php new file mode 100644 index 000000000..d48440ee4 --- /dev/null +++ b/spec/Validator/Order/OrderExistsValidatorSpec.php @@ -0,0 +1,63 @@ +beConstructedWith($orderRepository); + + $this->initialize($executionContext); + } + + function it_does_not_add_constraint_if_order_exists( + OrderInterface $order, + OrderRepositoryInterface $orderRepository, + ExecutionContextInterface $executionContext + ): void { + $orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN', 'state' => OrderInterface::STATE_NEW])->willReturn($order); + + $executionContext->addViolation(Argument::any())->shouldNotBeCalled(); + + $this->validate('ORDERTOKEN', new OrderExists(['state' => OrderInterface::STATE_NEW])); + } + + function it_does_not_add_constraint_if_order_exists_multi_state( + OrderInterface $order, + OrderRepositoryInterface $orderRepository, + ExecutionContextInterface $executionContext + ): void { + $orderRepository->findOneBy( + [ + 'tokenValue' => 'ORDERTOKEN', + 'state' => [OrderInterface::STATE_NEW, 'other_state'], + ])->willReturn($order); + + $executionContext->addViolation(Argument::any())->shouldNotBeCalled(); + + $this->validate('ORDERTOKEN', new OrderExists( + ['state' => [OrderInterface::STATE_NEW, 'other_state']] + )); + } + + function it_adds_constraint_if_order_does_not_exits_exists( + OrderRepositoryInterface $orderRepository, + ExecutionContextInterface $executionContext + ): void { + $orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN', 'state' => OrderInterface::STATE_NEW])->willReturn(null); + + $executionContext->addViolation('sylius.shop_api.order.not_exists')->shouldBeCalled(); + + $this->validate('ORDERTOKEN', new OrderExists(['state' => OrderInterface::STATE_NEW])); + } +} diff --git a/src/Command/Order/UpdatePaymentMethod.php b/src/Command/Order/UpdatePaymentMethod.php new file mode 100644 index 000000000..b9d1d2ba3 --- /dev/null +++ b/src/Command/Order/UpdatePaymentMethod.php @@ -0,0 +1,39 @@ +orderToken = $orderToken; + $this->paymentIdentifier = $paymentIdentifier; + $this->paymentMethod = $paymentMethod; + } + + public function orderToken(): string + { + return $this->orderToken; + } + + public function paymentIdentifier() + { + return $this->paymentIdentifier; + } + + public function paymentMethod(): string + { + return $this->paymentMethod; + } +} diff --git a/src/Controller/Order/UpdatePaymentMethodAction.php b/src/Controller/Order/UpdatePaymentMethodAction.php new file mode 100644 index 000000000..227342afe --- /dev/null +++ b/src/Controller/Order/UpdatePaymentMethodAction.php @@ -0,0 +1,59 @@ +viewHandler = $viewHandler; + $this->bus = $bus; + $this->validator = $validator; + $this->validationErrorViewFactory = $validationErrorViewFactory; + } + + public function __invoke(Request $request): Response + { + $updateRequest = new UpdatePaymentMethodRequest($request); + + $validationResults = $this->validator->validate($updateRequest); + if (0 !== count($validationResults)) { + return $this->viewHandler->handle( + View::create($this->validationErrorViewFactory->create($validationResults), + Response::HTTP_BAD_REQUEST + ) + ); + } + + $this->bus->dispatch($updateRequest->getCommand()); + + return $this->viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT)); + } +} diff --git a/src/Factory/Order/PlacedOrderViewFactory.php b/src/Factory/Order/PlacedOrderViewFactory.php index 66d6c869f..00f4f6b6c 100644 --- a/src/Factory/Order/PlacedOrderViewFactory.php +++ b/src/Factory/Order/PlacedOrderViewFactory.php @@ -66,6 +66,7 @@ public function create(OrderInterface $order, string $localeCode): PlacedOrderVi $placedOrderView->locale = $localeCode; $placedOrderView->checkoutState = $order->getCheckoutState(); $placedOrderView->checkoutCompletedAt = $order->getCheckoutCompletedAt()->format('c'); + $placedOrderView->paymentState = $order->getPaymentState(); $placedOrderView->totals = $this->totalViewFactory->create($order); $placedOrderView->tokenValue = $order->getTokenValue(); $placedOrderView->number = $order->getNumber(); diff --git a/src/Handler/Order/UpdatePaymentMethodHandler.php b/src/Handler/Order/UpdatePaymentMethodHandler.php new file mode 100644 index 000000000..66e403ab5 --- /dev/null +++ b/src/Handler/Order/UpdatePaymentMethodHandler.php @@ -0,0 +1,52 @@ +orderRepository = $orderRepository; + $this->paymentMethodRepository = $paymentMethodRepository; + } + + public function __invoke(UpdatePaymentMethod $choosePaymentMethod): void + { + /** @var OrderInterface $order */ + $order = $this->orderRepository->findOneBy(['tokenValue' => $choosePaymentMethod->orderToken()]); + + Assert::notNull($order, 'Order has not been found.'); + Assert::notSame(OrderInterface::STATE_CART, $order->getState(), 'Only orders can be updated.'); + Assert::same(OrderPaymentStates::STATE_AWAITING_PAYMENT, $order->getPaymentState(), 'Only awaiting payment orders can be updated.'); + + /** @var PaymentMethodInterface $paymentMethod */ + $paymentMethod = $this->paymentMethodRepository->findOneBy(['code' => $choosePaymentMethod->paymentMethod()]); + + Assert::notNull($paymentMethod, 'Payment method has not been found'); + Assert::true(isset($order->getPayments()[$choosePaymentMethod->paymentIdentifier()]), 'Can not find payment with given identifier.'); + + $payment = $order->getPayments()[$choosePaymentMethod->paymentIdentifier()]; + Assert::same(PaymentInterface::STATE_NEW, $payment->getState(), 'Payment should have new state'); + + $payment->setMethod($paymentMethod); + } +} diff --git a/src/Request/Order/UpdatePaymentMethodRequest.php b/src/Request/Order/UpdatePaymentMethodRequest.php new file mode 100644 index 000000000..039c8a28e --- /dev/null +++ b/src/Request/Order/UpdatePaymentMethodRequest.php @@ -0,0 +1,32 @@ +token = $request->attributes->get('token'); + $this->paymentIdentifier = $request->attributes->get('paymentId'); + $this->paymentMethod = $request->request->get('method'); + } + + public function getCommand(): UpdatePaymentMethod + { + return new UpdatePaymentMethod($this->token, $this->paymentIdentifier, $this->paymentMethod); + } +} diff --git a/src/Resources/config/routing/order.yml b/src/Resources/config/routing/order.yml index fa2215128..733f768da 100644 --- a/src/Resources/config/routing/order.yml +++ b/src/Resources/config/routing/order.yml @@ -9,3 +9,15 @@ sylius_shop_api_order_details: methods: [GET] defaults: _controller: sylius.shop_api_plugin.controller.order.show_order_details_action + +sylius_shop_api_order_available_payment_methods: + path: /orders/{token}/payment + methods: [GET] + defaults: + _controller: sylius.shop_api_plugin.controller.checkout.show_available_payment_methods_action + +sylius_shop_api_order_update_payment_method: + path: /orders/{token}/payment/{paymentId} + methods: [PUT] + defaults: + _controller: sylius.shop_api_plugin.controller.order.update_payment_method_action diff --git a/src/Resources/config/services/actions/order.xml b/src/Resources/config/services/actions/order.xml index e0d38092c..600cf23ff 100644 --- a/src/Resources/config/services/actions/order.xml +++ b/src/Resources/config/services/actions/order.xml @@ -19,5 +19,14 @@ + + + + + + + diff --git a/src/Resources/config/services/handler/order.xml b/src/Resources/config/services/handler/order.xml new file mode 100644 index 000000000..b3060fb39 --- /dev/null +++ b/src/Resources/config/services/handler/order.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/src/Resources/config/services/validators/order.xml b/src/Resources/config/services/validators/order.xml new file mode 100644 index 000000000..60b441a8b --- /dev/null +++ b/src/Resources/config/services/validators/order.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/src/Resources/config/validation/order/UpdatePaymentMethodRequest.xml b/src/Resources/config/validation/order/UpdatePaymentMethodRequest.xml new file mode 100644 index 000000000..539097739 --- /dev/null +++ b/src/Resources/config/validation/order/UpdatePaymentMethodRequest.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + diff --git a/src/Validator/Constraints/OrderExists.php b/src/Validator/Constraints/OrderExists.php new file mode 100644 index 000000000..47c9c7ce6 --- /dev/null +++ b/src/Validator/Constraints/OrderExists.php @@ -0,0 +1,23 @@ + */ + public $state = [OrderInterface::STATE_NEW, OrderInterface::STATE_FULFILLED, OrderInterface::STATE_CANCELLED]; + + public function validatedBy(): string + { + return OrderExistsValidator::class; + } +} diff --git a/src/Validator/Order/OrderExistsValidator.php b/src/Validator/Order/OrderExistsValidator.php new file mode 100644 index 000000000..efd9cfc57 --- /dev/null +++ b/src/Validator/Order/OrderExistsValidator.php @@ -0,0 +1,33 @@ +orderRepository = $orderRepository; + } + + public function validate($token, Constraint $constraint): void + { + if (!$constraint instanceof OrderExists) { + throw new UnexpectedTypeException($constraint, OrderExists::class); + } + + if (null === $this->orderRepository->findOneBy(['tokenValue' => $token, 'state' => $constraint->state])) { + $this->context->addViolation($constraint->message); + } + } +} diff --git a/src/View/Order/PlacedOrderView.php b/src/View/Order/PlacedOrderView.php index ae0ee106e..644a79212 100644 --- a/src/View/Order/PlacedOrderView.php +++ b/src/View/Order/PlacedOrderView.php @@ -28,6 +28,9 @@ class PlacedOrderView /** @var string */ public $checkoutCompletedAt; + /** @var string */ + public $paymentState; + /** @var array|ItemView[] */ public $items = []; diff --git a/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php b/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php new file mode 100644 index 000000000..2caafe61f --- /dev/null +++ b/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php @@ -0,0 +1,61 @@ +loadFixturesFromFiles(['customer.yml', 'country.yml', 'address.yml', 'shop.yml', 'payment.yml', 'shipping.yml', 'order.yml']); + $this->logInUser('oliver@queen.com', '123password'); + + $data = +<<client->request('PUT', $this->getPaymentUrl('ORDERTOKENPLACED2') . '/0', [], [], self::CONTENT_TYPE_HEADER, $data); + + $response = $this->client->getResponse(); + $this->assertResponseCode($response, Response::HTTP_NO_CONTENT); + } + + /** + * @test + */ + public function it_does_not_allow_to_update_payment_method_on_paid_order(): void + { + $fixtures = $this->loadFixturesFromFiles(['customer.yml', 'country.yml', 'address.yml', 'shop.yml', 'payment.yml', 'shipping.yml', 'order.yml']); + $this->logInUser('oliver@queen.com', '123password'); + + $data = +<<client->request('PUT', $this->getPaymentUrl('ORDERTOKENPAID') . '/0', [], [], self::CONTENT_TYPE_HEADER, $data); + + $response = $this->client->getResponse(); + $this->assertResponseCode($response, Response::HTTP_BAD_REQUEST); + } + + private function getPaymentUrl(string $token): string + { + return sprintf('/shop-api/WEB_GB/orders/%s/payment', $token); + } +} From 41ce42f0c49f5d6781fe2046feef5bf8bd79711a Mon Sep 17 00:00:00 2001 From: David Lobato Date: Tue, 30 Apr 2019 17:30:25 +0100 Subject: [PATCH 02/12] Fix tests --- spec/Command/Order/UpdatePaymentMethodSpec.php | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/Command/Order/UpdatePaymentMethodSpec.php b/spec/Command/Order/UpdatePaymentMethodSpec.php index 926040f50..5fa683f07 100644 --- a/spec/Command/Order/UpdatePaymentMethodSpec.php +++ b/spec/Command/Order/UpdatePaymentMethodSpec.php @@ -5,7 +5,6 @@ namespace spec\Sylius\ShopApiPlugin\Command\Order; use PhpSpec\ObjectBehavior; -use TypeError; final class UpdatePaymentMethodSpec extends ObjectBehavior { From 77ea84d97eab1cee7123cb6e1c6ae09b10213ae7 Mon Sep 17 00:00:00 2001 From: David Lobato Date: Mon, 6 May 2019 09:52:02 +0100 Subject: [PATCH 03/12] Rename UpdatePaymentMethod command properties. Fix typos. --- spec/Command/Order/UpdatePaymentMethodSpec.php | 4 ++-- .../Order/OrderExistsValidatorSpec.php | 2 +- src/Command/Order/UpdatePaymentMethod.php | 18 +++++++++--------- .../Order/UpdatePaymentMethodHandler.php | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/spec/Command/Order/UpdatePaymentMethodSpec.php b/spec/Command/Order/UpdatePaymentMethodSpec.php index 5fa683f07..8eaa45c76 100644 --- a/spec/Command/Order/UpdatePaymentMethodSpec.php +++ b/spec/Command/Order/UpdatePaymentMethodSpec.php @@ -20,11 +20,11 @@ function it_has_order_token(): void function it_has_identifier_of_payment(): void { - $this->paymentIdentifier()->shouldReturn(1); + $this->paymentId()->shouldReturn(1); } function it_has_payment_method_defined(): void { - $this->paymentMethod()->shouldReturn('CASH_ON_DELIVERY_METHOD'); + $this->paymentMethodCode()->shouldReturn('CASH_ON_DELIVERY_METHOD'); } } diff --git a/spec/Validator/Order/OrderExistsValidatorSpec.php b/spec/Validator/Order/OrderExistsValidatorSpec.php index d48440ee4..c76b98772 100644 --- a/spec/Validator/Order/OrderExistsValidatorSpec.php +++ b/spec/Validator/Order/OrderExistsValidatorSpec.php @@ -50,7 +50,7 @@ function it_does_not_add_constraint_if_order_exists_multi_state( )); } - function it_adds_constraint_if_order_does_not_exits_exists( + function it_adds_constraint_if_order_does_not_exists( OrderRepositoryInterface $orderRepository, ExecutionContextInterface $executionContext ): void { diff --git a/src/Command/Order/UpdatePaymentMethod.php b/src/Command/Order/UpdatePaymentMethod.php index b9d1d2ba3..8337650fd 100644 --- a/src/Command/Order/UpdatePaymentMethod.php +++ b/src/Command/Order/UpdatePaymentMethod.php @@ -10,16 +10,16 @@ class UpdatePaymentMethod protected $orderToken; /** @var mixed */ - protected $paymentIdentifier; + protected $paymentId; /** @var string */ - protected $paymentMethod; + protected $paymentMethodCode; - public function __construct(string $orderToken, $paymentIdentifier, string $paymentMethod) + public function __construct(string $orderToken, $paymentId, string $paymentMethodCode) { $this->orderToken = $orderToken; - $this->paymentIdentifier = $paymentIdentifier; - $this->paymentMethod = $paymentMethod; + $this->paymentId = $paymentId; + $this->paymentMethodCode = $paymentMethodCode; } public function orderToken(): string @@ -27,13 +27,13 @@ public function orderToken(): string return $this->orderToken; } - public function paymentIdentifier() + public function paymentId() { - return $this->paymentIdentifier; + return $this->paymentId; } - public function paymentMethod(): string + public function paymentMethodCode(): string { - return $this->paymentMethod; + return $this->paymentMethodCode; } } diff --git a/src/Handler/Order/UpdatePaymentMethodHandler.php b/src/Handler/Order/UpdatePaymentMethodHandler.php index 66e403ab5..9e50d3ff5 100644 --- a/src/Handler/Order/UpdatePaymentMethodHandler.php +++ b/src/Handler/Order/UpdatePaymentMethodHandler.php @@ -39,12 +39,12 @@ public function __invoke(UpdatePaymentMethod $choosePaymentMethod): void Assert::same(OrderPaymentStates::STATE_AWAITING_PAYMENT, $order->getPaymentState(), 'Only awaiting payment orders can be updated.'); /** @var PaymentMethodInterface $paymentMethod */ - $paymentMethod = $this->paymentMethodRepository->findOneBy(['code' => $choosePaymentMethod->paymentMethod()]); + $paymentMethod = $this->paymentMethodRepository->findOneBy(['code' => $choosePaymentMethod->paymentMethodCode()]); Assert::notNull($paymentMethod, 'Payment method has not been found'); - Assert::true(isset($order->getPayments()[$choosePaymentMethod->paymentIdentifier()]), 'Can not find payment with given identifier.'); + Assert::true(isset($order->getPayments()[$choosePaymentMethod->paymentId()]), 'Can not find payment with given identifier.'); - $payment = $order->getPayments()[$choosePaymentMethod->paymentIdentifier()]; + $payment = $order->getPayments()[$choosePaymentMethod->paymentId()]; Assert::same(PaymentInterface::STATE_NEW, $payment->getState(), 'Payment should have new state'); $payment->setMethod($paymentMethod); From 175eb0702b84273a74ecab2ff75659633d7da2a1 Mon Sep 17 00:00:00 2001 From: David Lobato Date: Fri, 10 May 2019 18:22:46 +0100 Subject: [PATCH 04/12] Update tests --- .../Order/OrderUpdatePaymentMethodApiTest.php | 22 ++++++++++++++----- .../order/order_details_response.json | 1 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php b/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php index 2caafe61f..fcd165cd5 100644 --- a/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php +++ b/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php @@ -6,19 +6,26 @@ use Symfony\Component\HttpFoundation\Response; use Tests\Sylius\ShopApiPlugin\Controller\JsonApiTestCase; +use Tests\Sylius\ShopApiPlugin\Controller\Utils\OrderPlacerTrait; use Tests\Sylius\ShopApiPlugin\Controller\Utils\ShopUserLoginTrait; final class OrderUpdatePaymentMethodApiTest extends JsonApiTestCase { use ShopUserLoginTrait; + use OrderPlacerTrait; /** * @test */ public function it_allows_to_update_payment_method(): void { - $fixtures = $this->loadFixturesFromFiles(['customer.yml', 'country.yml', 'address.yml', 'shop.yml', 'payment.yml', 'shipping.yml', 'order.yml']); - $this->logInUser('oliver@queen.com', '123password'); + $this->loadFixturesFromFiles(['customer.yml', 'country.yml', 'address.yml', 'shop.yml', 'payment.yml', 'shipping.yml']); + $token = 'ORDERTOKENPLACED'; + $email = 'oliver@queen.com'; + + $this->logInUser($email, '123password'); + + $this->placeOrderForCustomerWithEmail($email, $token); $data = <<client->request('PUT', $this->getPaymentUrl('ORDERTOKENPLACED2') . '/0', [], [], self::CONTENT_TYPE_HEADER, $data); + $this->client->request('PUT', $this->getPaymentUrl('ORDERTOKENPLACED') . '/0', [], [], self::CONTENT_TYPE_HEADER, $data); $response = $this->client->getResponse(); $this->assertResponseCode($response, Response::HTTP_NO_CONTENT); @@ -38,8 +45,13 @@ public function it_allows_to_update_payment_method(): void */ public function it_does_not_allow_to_update_payment_method_on_paid_order(): void { - $fixtures = $this->loadFixturesFromFiles(['customer.yml', 'country.yml', 'address.yml', 'shop.yml', 'payment.yml', 'shipping.yml', 'order.yml']); - $this->logInUser('oliver@queen.com', '123password'); + $this->loadFixturesFromFiles(['customer.yml', 'country.yml', 'address.yml', 'shop.yml', 'payment.yml', 'shipping.yml']); + $token = 'ORDERTOKENPAID'; + $email = 'oliver@queen.com'; + + $this->logInUser($email, '123password'); + + $this->placeOrderForCustomerWithEmail($email, $token); $data = << Date: Fri, 10 May 2019 18:40:35 +0100 Subject: [PATCH 05/12] Fix test --- tests/Responses/Expected/order/orders_list_response.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Responses/Expected/order/orders_list_response.json b/tests/Responses/Expected/order/orders_list_response.json index 7b7ba7879..4068a47d7 100644 --- a/tests/Responses/Expected/order/orders_list_response.json +++ b/tests/Responses/Expected/order/orders_list_response.json @@ -5,6 +5,7 @@ "locale": "en_GB", "checkoutState": "completed", "checkoutCompletedAt": "@string@.isDateTime()", + "paymentState": "awaiting_payment", "items": [ { "id": @integer@, From 10050cc7bfe4349fc676c18651f0f25b89543b74 Mon Sep 17 00:00:00 2001 From: mamazu <14860264+mamazu@users.noreply.github.com> Date: Wed, 5 Feb 2020 00:31:25 +0100 Subject: [PATCH 06/12] Fixing tests --- .../Order/UpdatePaymentMethodRequest.php | 10 +++++ .../config/services/validators/order.xml | 6 +++ .../order/UpdatePaymentMethodRequest.xml | 2 + src/Validator/Constraints/PaymentNotPaid.php | 26 ++++++++++++ src/Validator/Order/OrderExistsValidator.php | 6 --- .../Order/PaymentNotPaidValidator.php | 42 +++++++++++++++++++ .../Order/OrderUpdatePaymentMethodApiTest.php | 17 +++++++- .../order/order_details_response_guest.json | 1 + 8 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 src/Validator/Constraints/PaymentNotPaid.php create mode 100644 src/Validator/Order/PaymentNotPaidValidator.php diff --git a/src/Request/Order/UpdatePaymentMethodRequest.php b/src/Request/Order/UpdatePaymentMethodRequest.php index 039c8a28e..8396e4a0e 100644 --- a/src/Request/Order/UpdatePaymentMethodRequest.php +++ b/src/Request/Order/UpdatePaymentMethodRequest.php @@ -29,4 +29,14 @@ public function getCommand(): UpdatePaymentMethod { return new UpdatePaymentMethod($this->token, $this->paymentIdentifier, $this->paymentMethod); } + + public function getOrderToken() : string + { + return $this->token; + } + + public function getPaymentId() + { + return $this->paymentIdentifier; + } } diff --git a/src/Resources/config/services/validators/order.xml b/src/Resources/config/services/validators/order.xml index 60b441a8b..b1e4efe29 100644 --- a/src/Resources/config/services/validators/order.xml +++ b/src/Resources/config/services/validators/order.xml @@ -7,5 +7,11 @@ + + + + + diff --git a/src/Resources/config/validation/order/UpdatePaymentMethodRequest.xml b/src/Resources/config/validation/order/UpdatePaymentMethodRequest.xml index 539097739..616ca3e10 100644 --- a/src/Resources/config/validation/order/UpdatePaymentMethodRequest.xml +++ b/src/Resources/config/validation/order/UpdatePaymentMethodRequest.xml @@ -21,5 +21,7 @@ + + diff --git a/src/Validator/Constraints/PaymentNotPaid.php b/src/Validator/Constraints/PaymentNotPaid.php new file mode 100644 index 000000000..4992c9c00 --- /dev/null +++ b/src/Validator/Constraints/PaymentNotPaid.php @@ -0,0 +1,26 @@ +orderRepository->findOneBy(['tokenValue' => $token, 'state' => $constraint->state])) { $this->context->addViolation($constraint->message); } diff --git a/src/Validator/Order/PaymentNotPaidValidator.php b/src/Validator/Order/PaymentNotPaidValidator.php new file mode 100644 index 000000000..d6fab5670 --- /dev/null +++ b/src/Validator/Order/PaymentNotPaidValidator.php @@ -0,0 +1,42 @@ +orderRepository = $orderRepository; + } + + public function validate($updatePayment, Constraint $constraint): void + { + /** @var OrderInterface|null $order */ + $order = $this->orderRepository->findOneBy(['tokenValue' => $updatePayment->getOrderToken()]); + if($order === null) { + return; + } + + $payment = $order->getPayments()[$updatePayment->getPaymentId()] ?? null; + if ($payment === null) { + return; + } + + + if (!in_array($payment->getState(), [PaymentInterface::STATE_NEW, PaymentInterface::STATE_CANCELLED])) + { + $this->context->addViolation($constraint->message); + } + } +} diff --git a/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php b/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php index fcd165cd5..05e3ab41e 100644 --- a/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php +++ b/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php @@ -4,6 +4,9 @@ namespace Tests\Sylius\ShopApiPlugin\Controller\Order; +use Sylius\Component\Core\Model\OrderInterface; +use Sylius\Component\Core\Model\PaymentInterface; +use Sylius\Component\Core\OrderPaymentStates; use Symfony\Component\HttpFoundation\Response; use Tests\Sylius\ShopApiPlugin\Controller\JsonApiTestCase; use Tests\Sylius\ShopApiPlugin\Controller\Utils\OrderPlacerTrait; @@ -52,6 +55,7 @@ public function it_does_not_allow_to_update_payment_method_on_paid_order(): void $this->logInUser($email, '123password'); $this->placeOrderForCustomerWithEmail($email, $token); + $this->markOrderAsPayed($token); $data = <<assertResponseCode($response, Response::HTTP_BAD_REQUEST); } + private function markOrderAsPayed() { + /** @var OrderInterface $order */ + $order = $this->get('sylius.repository.order')->findAll()[0]; + foreach($order->getPayments() as $payment) { + $payment->setState(PaymentInterface::STATE_COMPLETED); + } + $order->setPaymentState(OrderPaymentStates::STATE_PAID); + + $this->get('sylius.manager.order')->flush(); + } + private function getPaymentUrl(string $token): string { - return sprintf('/shop-api/WEB_GB/orders/%s/payment', $token); + return sprintf('/shop-api/orders/%s/payment', $token); } } diff --git a/tests/Responses/Expected/order/order_details_response_guest.json b/tests/Responses/Expected/order/order_details_response_guest.json index 397c879f8..a1d44cea6 100644 --- a/tests/Responses/Expected/order/order_details_response_guest.json +++ b/tests/Responses/Expected/order/order_details_response_guest.json @@ -4,6 +4,7 @@ "locale": "en_GB", "checkoutState": "completed", "checkoutCompletedAt": "@string@.isDateTime()", + "paymentState": "awaiting_payment", "items": [ { "id": @integer@, From 6db288efbfda18c2ffdd69e2fb84dfb4f1c3ddf5 Mon Sep 17 00:00:00 2001 From: David Lobato Date: Thu, 6 Feb 2020 10:25:29 +0000 Subject: [PATCH 07/12] Fix code style --- src/Request/Order/UpdatePaymentMethodRequest.php | 2 +- src/Validator/Constraints/PaymentNotPaid.php | 1 - src/Validator/Order/PaymentNotPaidValidator.php | 8 +++----- .../Controller/Order/OrderUpdatePaymentMethodApiTest.php | 5 +++-- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Request/Order/UpdatePaymentMethodRequest.php b/src/Request/Order/UpdatePaymentMethodRequest.php index 8396e4a0e..952913a8e 100644 --- a/src/Request/Order/UpdatePaymentMethodRequest.php +++ b/src/Request/Order/UpdatePaymentMethodRequest.php @@ -30,7 +30,7 @@ public function getCommand(): UpdatePaymentMethod return new UpdatePaymentMethod($this->token, $this->paymentIdentifier, $this->paymentMethod); } - public function getOrderToken() : string + public function getOrderToken(): string { return $this->token; } diff --git a/src/Validator/Constraints/PaymentNotPaid.php b/src/Validator/Constraints/PaymentNotPaid.php index 4992c9c00..6b28e1914 100644 --- a/src/Validator/Constraints/PaymentNotPaid.php +++ b/src/Validator/Constraints/PaymentNotPaid.php @@ -4,7 +4,6 @@ namespace Sylius\ShopApiPlugin\Validator\Constraints; -use Sylius\Component\Order\Model\OrderInterface; use Sylius\ShopApiPlugin\Validator\Order\PaymentNotPaidValidator; use Symfony\Component\Validator\Constraint; diff --git a/src/Validator/Order/PaymentNotPaidValidator.php b/src/Validator/Order/PaymentNotPaidValidator.php index d6fab5670..1641d8cf9 100644 --- a/src/Validator/Order/PaymentNotPaidValidator.php +++ b/src/Validator/Order/PaymentNotPaidValidator.php @@ -4,9 +4,9 @@ namespace Sylius\ShopApiPlugin\Validator\Order; -use Sylius\Component\Core\Repository\OrderRepositoryInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\PaymentInterface; +use Sylius\Component\Core\Repository\OrderRepositoryInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; @@ -24,7 +24,7 @@ public function validate($updatePayment, Constraint $constraint): void { /** @var OrderInterface|null $order */ $order = $this->orderRepository->findOneBy(['tokenValue' => $updatePayment->getOrderToken()]); - if($order === null) { + if ($order === null) { return; } @@ -33,9 +33,7 @@ public function validate($updatePayment, Constraint $constraint): void return; } - - if (!in_array($payment->getState(), [PaymentInterface::STATE_NEW, PaymentInterface::STATE_CANCELLED])) - { + if (!in_array($payment->getState(), [PaymentInterface::STATE_NEW, PaymentInterface::STATE_CANCELLED])) { $this->context->addViolation($constraint->message); } } diff --git a/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php b/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php index 05e3ab41e..e5ef5fc75 100644 --- a/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php +++ b/tests/Controller/Order/OrderUpdatePaymentMethodApiTest.php @@ -70,10 +70,11 @@ public function it_does_not_allow_to_update_payment_method_on_paid_order(): void $this->assertResponseCode($response, Response::HTTP_BAD_REQUEST); } - private function markOrderAsPayed() { + private function markOrderAsPayed() + { /** @var OrderInterface $order */ $order = $this->get('sylius.repository.order')->findAll()[0]; - foreach($order->getPayments() as $payment) { + foreach ($order->getPayments() as $payment) { $payment->setState(PaymentInterface::STATE_COMPLETED); } $order->setPaymentState(OrderPaymentStates::STATE_PAID); From 54f0cb01101fc62c3a3874287e5f09423bcfa179 Mon Sep 17 00:00:00 2001 From: David Lobato Date: Thu, 6 Feb 2020 14:11:33 +0000 Subject: [PATCH 08/12] Update src/Request/Order/UpdatePaymentMethodRequest.php Co-Authored-By: mamazu <14860264+mamazu@users.noreply.github.com> --- src/Request/Order/UpdatePaymentMethodRequest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Request/Order/UpdatePaymentMethodRequest.php b/src/Request/Order/UpdatePaymentMethodRequest.php index 952913a8e..8e801272a 100644 --- a/src/Request/Order/UpdatePaymentMethodRequest.php +++ b/src/Request/Order/UpdatePaymentMethodRequest.php @@ -35,6 +35,7 @@ public function getOrderToken(): string return $this->token; } + /** @return int|string */ public function getPaymentId() { return $this->paymentIdentifier; From f8d3d3b5ccaf05be2740b6d3fddb2585437b97cc Mon Sep 17 00:00:00 2001 From: David Lobato Date: Thu, 6 Feb 2020 14:11:50 +0000 Subject: [PATCH 09/12] Update src/Command/Order/UpdatePaymentMethod.php Co-Authored-By: mamazu <14860264+mamazu@users.noreply.github.com> --- src/Command/Order/UpdatePaymentMethod.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Command/Order/UpdatePaymentMethod.php b/src/Command/Order/UpdatePaymentMethod.php index 8337650fd..d64dc5420 100644 --- a/src/Command/Order/UpdatePaymentMethod.php +++ b/src/Command/Order/UpdatePaymentMethod.php @@ -15,6 +15,7 @@ class UpdatePaymentMethod /** @var string */ protected $paymentMethodCode; + /** @param int|string $paymentId */ public function __construct(string $orderToken, $paymentId, string $paymentMethodCode) { $this->orderToken = $orderToken; From c11044fafc3a84e15a09c60631c96da2ea821300 Mon Sep 17 00:00:00 2001 From: David Lobato Date: Thu, 6 Feb 2020 14:13:01 +0000 Subject: [PATCH 10/12] Apply suggestions from code review Co-Authored-By: mamazu <14860264+mamazu@users.noreply.github.com> --- src/Command/Order/UpdatePaymentMethod.php | 1 + src/Validator/Order/OrderExistsValidator.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Command/Order/UpdatePaymentMethod.php b/src/Command/Order/UpdatePaymentMethod.php index d64dc5420..6301818a6 100644 --- a/src/Command/Order/UpdatePaymentMethod.php +++ b/src/Command/Order/UpdatePaymentMethod.php @@ -28,6 +28,7 @@ public function orderToken(): string return $this->orderToken; } + /** @return string|int */ public function paymentId() { return $this->paymentId; diff --git a/src/Validator/Order/OrderExistsValidator.php b/src/Validator/Order/OrderExistsValidator.php index 1a6481006..970090a22 100644 --- a/src/Validator/Order/OrderExistsValidator.php +++ b/src/Validator/Order/OrderExistsValidator.php @@ -21,6 +21,7 @@ public function __construct(OrderRepositoryInterface $orderRepository) public function validate($token, Constraint $constraint): void { if (null === $this->orderRepository->findOneBy(['tokenValue' => $token, 'state' => $constraint->state])) { + /** @var Sylius\ShopApiPlugin\Validator\Constraints\OrderExists $constraint */ $this->context->addViolation($constraint->message); } } From 891b17989c2893d48c8e6cd4818e7d87cd6a57bb Mon Sep 17 00:00:00 2001 From: David Lobato Date: Thu, 6 Feb 2020 15:58:52 +0000 Subject: [PATCH 11/12] Apply suggestions from code review Co-Authored-By: mamazu <14860264+mamazu@users.noreply.github.com> --- src/Validator/Order/OrderExistsValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Validator/Order/OrderExistsValidator.php b/src/Validator/Order/OrderExistsValidator.php index 970090a22..0a99165d1 100644 --- a/src/Validator/Order/OrderExistsValidator.php +++ b/src/Validator/Order/OrderExistsValidator.php @@ -20,8 +20,8 @@ public function __construct(OrderRepositoryInterface $orderRepository) public function validate($token, Constraint $constraint): void { + /** @var Sylius\ShopApiPlugin\Validator\Constraints\OrderExists $constraint */ if (null === $this->orderRepository->findOneBy(['tokenValue' => $token, 'state' => $constraint->state])) { - /** @var Sylius\ShopApiPlugin\Validator\Constraints\OrderExists $constraint */ $this->context->addViolation($constraint->message); } } From a2d10f7f5d8f60e31acb79553f85ce34c135bece Mon Sep 17 00:00:00 2001 From: David Lobato Date: Fri, 7 Feb 2020 09:54:07 +0000 Subject: [PATCH 12/12] Proper type handling on OrderExistsValidator --- src/Validator/Constraints/OrderExists.php | 2 +- src/Validator/Order/OrderExistsValidator.php | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Validator/Constraints/OrderExists.php b/src/Validator/Constraints/OrderExists.php index 47c9c7ce6..ad0542477 100644 --- a/src/Validator/Constraints/OrderExists.php +++ b/src/Validator/Constraints/OrderExists.php @@ -13,7 +13,7 @@ final class OrderExists extends Constraint /** @var string */ public $message = 'sylius.shop_api.order.not_exists'; - /** @var string|array */ + /** @var array|string[] */ public $state = [OrderInterface::STATE_NEW, OrderInterface::STATE_FULFILLED, OrderInterface::STATE_CANCELLED]; public function validatedBy(): string diff --git a/src/Validator/Order/OrderExistsValidator.php b/src/Validator/Order/OrderExistsValidator.php index 0a99165d1..e687c01b2 100644 --- a/src/Validator/Order/OrderExistsValidator.php +++ b/src/Validator/Order/OrderExistsValidator.php @@ -5,8 +5,10 @@ namespace Sylius\ShopApiPlugin\Validator\Order; use Sylius\Component\Core\Repository\OrderRepositoryInterface; +use Sylius\ShopApiPlugin\Validator\Constraints\OrderExists; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; +use Webmozart\Assert\Assert; final class OrderExistsValidator extends ConstraintValidator { @@ -20,7 +22,8 @@ public function __construct(OrderRepositoryInterface $orderRepository) public function validate($token, Constraint $constraint): void { - /** @var Sylius\ShopApiPlugin\Validator\Constraints\OrderExists $constraint */ + Assert::isInstanceOf($constraint, OrderExists::class); + if (null === $this->orderRepository->findOneBy(['tokenValue' => $token, 'state' => $constraint->state])) { $this->context->addViolation($constraint->message); }