{{ form_row(itemForm.quantity) }} |
- {{ orderItem.productName }} | {# todo add variant #}
+ {{ orderItem.productName }} |
+ {{ orderItem.variantName }} |
{{ money.format(orderItem.unitPrice, order.currencyCode) }} |
{{ money.format(orderItem.total, order.currencyCode) }} |
diff --git a/tests/Application/config/routes/setono_sylius_order_edit.yaml b/tests/Application/config/routes/setono_sylius_order_edit.yaml
new file mode 100644
index 0000000..3dab0fb
--- /dev/null
+++ b/tests/Application/config/routes/setono_sylius_order_edit.yaml
@@ -0,0 +1,2 @@
+setono_sylius_edit_order:
+ resource: "@SetonoSyliusOrderEditPlugin/Resources/config/routes.yaml"
diff --git a/tests/Application/templates/bundles/SyliusAdminBundle/Order/Update/_content.html.twig b/tests/Application/templates/bundles/SyliusAdminBundle/Order/Update/_content.html.twig
index bd9383b..63e27dc 100644
--- a/tests/Application/templates/bundles/SyliusAdminBundle/Order/Update/_content.html.twig
+++ b/tests/Application/templates/bundles/SyliusAdminBundle/Order/Update/_content.html.twig
@@ -1,8 +1,8 @@
{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %}
-{{ form_start(form, {'action': path('sylius_admin_order_update', {'id': order.id}), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }}
+{{ form_start(form, {'action': path('setono_sylius_order_edit_admin_update', {'id': order.id}), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }}
-
+
{{ include('@SetonoSyliusOrderEditPlugin/admin/order/update/_order_items.html.twig') }}
@@ -24,7 +24,6 @@
{{ sylius_template_event('sylius.admin.order.update.form', {'resource': resource}) }}
- {{ form_row(form._token) }}
{% include '@SyliusUi/Form/Buttons/_update.html.twig' with {'paths': {'cancel': sylius_generate_redirect_path(path('sylius_admin_order_index'))}} %}
{{ form_end(form, {'render_rest': false}) }}
diff --git a/tests/DependencyInjection/SetonoSyliusOrderEditExtensionTest.php b/tests/DependencyInjection/SetonoSyliusOrderEditExtensionTest.php
deleted file mode 100644
index ce8378d..0000000
--- a/tests/DependencyInjection/SetonoSyliusOrderEditExtensionTest.php
+++ /dev/null
@@ -1,29 +0,0 @@
-load();
- }
-}
diff --git a/tests/Functional/OrderUpdateTest.php b/tests/Functional/OrderUpdateTest.php
new file mode 100644
index 0000000..ee99184
--- /dev/null
+++ b/tests/Functional/OrderUpdateTest.php
@@ -0,0 +1,162 @@
+ 'test', 'debug' => true]);
+ }
+
+ public function testItUpdatesOrder(): void
+ {
+ $this->makeVariantTrackedWithStock();
+ $order = $this->placeOrderProgramatically(quantity: 5);
+
+ /** @var ProductVariantInterface $variant */
+ $variant = $this->getVariantRepository()->findOneBy(['code' => '000F_office_grey_jeans-variant-0']);
+ $initialHold = $variant->getOnHold();
+
+ $this->loginAsAdmin();
+ $this->updateOrder($order->getId());
+
+ self::assertResponseStatusCodeSame(302);
+
+ $order = $this->getOrderRepository()->findOneBy(['tokenValue' => 'TOKEN']);
+ self::assertSame(3, $order->getItems()->first()->getQuantity());
+
+ $variant = $this->getVariantRepository()->findOneBy(['code' => '000F_office_grey_jeans-variant-0']);
+ self::assertSame($initialHold - 2, $variant->getOnHold());
+ }
+
+ private function placeOrderProgramatically(
+ string $variantCode = '000F_office_grey_jeans-variant-0',
+ int $quantity = 1,
+ ): Order {
+ /** @var MessageBusInterface $commandBus */
+ $commandBus = self::getContainer()->get('sylius.command_bus');
+
+ $pickupCart = new PickupCart('TOKEN');
+ $pickupCart->setLocaleCode('en_US');
+ $pickupCart->setChannelCode('FASHION_WEB');
+ $pickupCart->setEmail('shop@example.com');
+ $commandBus->dispatch($pickupCart);
+
+ $orderRepository = self::getContainer()->get('sylius.repository.order');
+ /** @var OrderInterface $order */
+ $order = $orderRepository->findOneBy(['tokenValue' => 'TOKEN']);
+
+ $addToCartCommand = new AddItemToCart($variantCode, $quantity);
+ $addToCartCommand->setOrderTokenValue('TOKEN');
+ $commandBus->dispatch($addToCartCommand);
+
+ $address = new Address();
+ $address->setFirstName('John');
+ $address->setLastName('Doe');
+ $address->setCountryCode('US');
+ $address->setCity('New York');
+ $address->setStreet('Wall Street');
+ $address->setPostcode('00-001');
+ $addressCart = new UpdateCart(billingAddress: $address, shippingAddress: $address);
+ $addressCart->setOrderTokenValue('TOKEN');
+ $commandBus->dispatch($addressCart);
+
+ $chooseShippingMethod = new ChooseShippingMethod('dhl_express');
+ $chooseShippingMethod->setOrderTokenValue('TOKEN');
+ $chooseShippingMethod->setSubresourceId((string) $order->getShipments()->first()->getId());
+ $commandBus->dispatch($chooseShippingMethod);
+
+ $choosePaymentMethod = new ChoosePaymentMethod('bank_transfer');
+ $choosePaymentMethod->setOrderTokenValue('TOKEN');
+ $choosePaymentMethod->setSubresourceId((string) $order->getPayments()->first()->getId());
+ $commandBus->dispatch($choosePaymentMethod);
+
+ $completeOrder = new CompleteOrder();
+ $completeOrder->setOrderTokenValue('TOKEN');
+ $commandBus->dispatch($completeOrder);
+
+ return $this->getOrderRepository()->findOneBy(['tokenValue' => 'TOKEN']);
+ }
+
+ private function makeVariantTrackedWithStock(string $code = '000F_office_grey_jeans-variant-0', int $stock = 10): void
+ {
+ $variantRepository = self::getContainer()->get('sylius.repository.product_variant');
+ /** @var ProductVariantInterface $variant */
+ $variant = $variantRepository->findOneBy(['code' => $code]);
+ $variant->setTracked(true);
+ $variant->setOnHand($stock);
+ $variant->getOnHold(0);
+
+ self::getContainer()->get('sylius.manager.product_variant')->flush();
+ }
+
+ protected function tearDown(): void
+ {
+ $order = $this->getOrderRepository()->findOneBy(['tokenValue' => 'TOKEN']);
+ $orderManager = self::getContainer()->get('sylius.manager.order');
+ $orderManager->remove($order);
+ $orderManager->flush();
+ }
+
+ private function loginAsAdmin(): void
+ {
+ $crawler = static::$client->request('GET', '/admin/login');
+ $form = $crawler->selectButton('Login')->form([
+ '_username' => 'sylius@example.com',
+ '_password' => 'sylius',
+ ]);
+
+ static::$client->submit($form);
+ }
+
+ private function updateOrder(int $orderId): void
+ {
+ static::$client->request(
+ 'PATCH',
+ sprintf('/admin/orders/%d/update-and-process', $orderId),
+ [],
+ [],
+ ['CONTENT_TYPE' => 'application/json'],
+ json_encode([
+ 'sylius_order' => [
+ 'items' => [
+ ['quantity' => 3],
+ ],
+ ],
+ ]),
+ );
+ }
+
+ private function getOrderRepository(): OrderRepositoryInterface
+ {
+ return self::getContainer()->get('sylius.repository.order');
+ }
+
+ private function getVariantRepository(): ProductVariantRepositoryInterface
+ {
+ return self::getContainer()->get('sylius.repository.product_variant');
+ }
+}
diff --git a/tests/Unit/Checker/PostUpdateChangesCheckerTest.php b/tests/Unit/Checker/PostUpdateChangesCheckerTest.php
new file mode 100644
index 0000000..3d0538d
--- /dev/null
+++ b/tests/Unit/Checker/PostUpdateChangesCheckerTest.php
@@ -0,0 +1,61 @@
+expectException(NewOrderWrongTotalException::class);
+
+ $validator = new PostUpdateChangesChecker();
+
+ $newOrder = $this->prophesize(OrderInterface::class);
+ $newOrder->getTotal()->willReturn(1000);
+
+ $previousOrder = $this->prophesize(OrderInterface::class);
+ $previousOrder->getTotal()->willReturn(500);
+
+ $validator->check($previousOrder->reveal(), $newOrder->reveal());
+ }
+
+ public function testItDoesNothingIfNewOrderTotalIsSmallerThanThePreviousOne(): void
+ {
+ $validator = new PostUpdateChangesChecker();
+
+ $newOrder = $this->prophesize(OrderInterface::class);
+ $newOrder->getTotal()->willReturn(500);
+
+ $previousOrder = $this->prophesize(OrderInterface::class);
+ $previousOrder->getTotal()->willReturn(1000);
+
+ $this->expectNotToPerformAssertions();
+
+ $validator->check($previousOrder->reveal(), $newOrder->reveal());
+ }
+
+ public function testItDoesNothingIfNewOrderTotalIsEqualToThePreviousOne(): void
+ {
+ $validator = new PostUpdateChangesChecker();
+
+ $newOrder = $this->prophesize(OrderInterface::class);
+ $newOrder->getTotal()->willReturn(500);
+
+ $previousOrder = $this->prophesize(OrderInterface::class);
+ $previousOrder->getTotal()->willReturn(500);
+
+ $this->expectNotToPerformAssertions();
+
+ $validator->check($previousOrder->reveal(), $newOrder->reveal());
+ }
+}
diff --git a/tests/Unit/OrderProcessing/OrderPaymentProcessorTest.php b/tests/Unit/OrderProcessing/OrderPaymentProcessorTest.php
new file mode 100644
index 0000000..fd74b88
--- /dev/null
+++ b/tests/Unit/OrderProcessing/OrderPaymentProcessorTest.php
@@ -0,0 +1,50 @@
+prophesize(OrderProcessorInterface::class);
+ $requestStack = $this->prophesize(RequestStack::class);
+ $request = new Request([], [], ['_route' => 'setono_sylius_order_edit_admin_update']);
+ $requestStack->getCurrentRequest()->willReturn($request);
+
+ $processor = new OrderPaymentProcessor($orderProcessor->reveal(), $requestStack->reveal());
+
+ $order = $this->prophesize(OrderInterface::class);
+
+ $orderProcessor->process($order)->shouldNotBeCalled();
+
+ $processor->process($order->reveal());
+ }
+
+ public function testItDoesNothingIfItsDifferentRoute(): void
+ {
+ $orderProcessor = $this->prophesize(OrderProcessorInterface::class);
+ $requestStack = $this->prophesize(RequestStack::class);
+ $request = new Request([], [], ['_route' => 'some_other_route']);
+ $requestStack->getCurrentRequest()->willReturn($request);
+
+ $processor = new OrderPaymentProcessor($orderProcessor->reveal(), $requestStack->reveal());
+
+ $order = $this->prophesize(OrderInterface::class);
+
+ $orderProcessor->process($order)->shouldBeCalled();
+
+ $processor->process($order->reveal());
+ }
+}
diff --git a/tests/Unit/Processor/UpdatedOrderProcessorTest.php b/tests/Unit/Processor/UpdatedOrderProcessorTest.php
new file mode 100644
index 0000000..62449ea
--- /dev/null
+++ b/tests/Unit/Processor/UpdatedOrderProcessorTest.php
@@ -0,0 +1,40 @@
+prophesize(OrderProcessorInterface::class);
+ $orderInventoryOperator = $this->prophesize(OrderInventoryOperatorInterface::class);
+ $afterCheckoutOrderPaymentProcessor = $this->prophesize(OrderProcessorInterface::class);
+
+ $processor = new UpdatedOrderProcessor(
+ $orderProcessor->reveal(),
+ $orderInventoryOperator->reveal(),
+ $afterCheckoutOrderPaymentProcessor->reveal(),
+ );
+
+ $newOrder = $this->prophesize(OrderInterface::class);
+
+ $newOrder->setState('cart')->shouldBeCalled();
+ $orderProcessor->process($newOrder)->shouldBeCalled();
+ $afterCheckoutOrderPaymentProcessor->process($newOrder)->shouldBeCalled();
+ $newOrder->setState('new')->shouldBeCalled();
+ $orderInventoryOperator->hold($newOrder)->shouldBeCalled();
+
+ self::assertSame($newOrder->reveal(), $processor->process($newOrder->reveal()));
+ }
+}
diff --git a/tests/Unit/Provider/OrderPreparerTest.php b/tests/Unit/Provider/OrderPreparerTest.php
new file mode 100644
index 0000000..70607ca
--- /dev/null
+++ b/tests/Unit/Provider/OrderPreparerTest.php
@@ -0,0 +1,51 @@
+prophesize(OrderRepositoryInterface::class);
+ $inventoryOperator = $this->prophesize(OrderInventoryOperatorInterface::class);
+
+ $provider = new OrderPreparer(
+ $orderRepository->reveal(),
+ $inventoryOperator->reveal(),
+ );
+
+ $order = new Order();
+ $orderRepository->find(1)->willReturn($order);
+ $inventoryOperator->cancel($order)->shouldBeCalled();
+
+ self::assertSame($order, $provider->prepareToUpdate(1));
+ }
+
+ public function testItThrowsExceptionIfOrderWithGivenIdDoesNotExist(): void
+ {
+ $orderRepository = $this->prophesize(OrderRepositoryInterface::class);
+ $inventoryOperator = $this->prophesize(OrderInventoryOperatorInterface::class);
+
+ $provider = new OrderPreparer(
+ $orderRepository->reveal(),
+ $inventoryOperator->reveal(),
+ );
+
+ $orderRepository->find(1)->willReturn(null);
+
+ $this->expectException(\InvalidArgumentException::class);
+
+ $provider->prepareToUpdate(1);
+ }
+}
diff --git a/tests/Unit/Provider/UpdatedOrderProviderTest.php b/tests/Unit/Provider/UpdatedOrderProviderTest.php
new file mode 100644
index 0000000..2b259e8
--- /dev/null
+++ b/tests/Unit/Provider/UpdatedOrderProviderTest.php
@@ -0,0 +1,102 @@
+prophesize(FormFactoryInterface::class);
+ $form = $this->prophesize(FormInterface::class);
+
+ $provider = new UpdatedOrderProvider($formFactory->reveal());
+ $order = new Order();
+ $newOrder = new Order();
+ $request = new Request();
+
+ $formFactory->create(OrderType::class, $order, ['validation_groups' => 'sylius', 'csrf_protection' => false])->willReturn($form);
+ $form->handleRequest($request)->shouldBeCalled()->willReturn($form);
+
+ $form->isSubmitted()->willReturn(true);
+ $form->isValid()->willReturn(true);
+
+ $form->getData()->willReturn($newOrder);
+
+ self::assertSame($newOrder, $provider->provideFromOldOrderAndRequest($order, $request));
+ }
+
+ public function testItThrowsExceptionIfFormIsNotSubmitted(): void
+ {
+ $formFactory = $this->prophesize(FormFactoryInterface::class);
+ $form = $this->prophesize(FormInterface::class);
+
+ $provider = new UpdatedOrderProvider($formFactory->reveal());
+ $order = new Order();
+ $request = new Request();
+
+ $formFactory->create(OrderType::class, $order, ['validation_groups' => 'sylius', 'csrf_protection' => false])->willReturn($form);
+ $form->handleRequest($request)->shouldBeCalled()->willReturn($form);
+
+ $form->isSubmitted()->willReturn(false);
+
+ $this->expectException(OrderUpdateException::class);
+
+ $provider->provideFromOldOrderAndRequest($order, $request);
+ }
+
+ public function testItThrowsExceptionIfFormIsNotValid(): void
+ {
+ $formFactory = $this->prophesize(FormFactoryInterface::class);
+ $form = $this->prophesize(FormInterface::class);
+
+ $provider = new UpdatedOrderProvider($formFactory->reveal());
+ $order = new Order();
+ $request = new Request();
+
+ $formFactory->create(OrderType::class, $order, ['validation_groups' => 'sylius', 'csrf_protection' => false])->willReturn($form);
+ $form->handleRequest($request)->shouldBeCalled()->willReturn($form);
+
+ $form->isSubmitted()->willReturn(true);
+ $form->isValid()->willReturn(false);
+
+ $this->expectException(OrderUpdateException::class);
+
+ $provider->provideFromOldOrderAndRequest($order, $request);
+ }
+
+ public function testItThrowsExceptionIfFormDataIsNotOrder(): void
+ {
+ $formFactory = $this->prophesize(FormFactoryInterface::class);
+ $form = $this->prophesize(FormInterface::class);
+
+ $provider = new UpdatedOrderProvider($formFactory->reveal());
+ $order = new Order();
+ $request = new Request();
+
+ $formFactory->create(OrderType::class, $order, ['validation_groups' => 'sylius', 'csrf_protection' => false])->willReturn($form);
+ $form->handleRequest($request)->shouldBeCalled()->willReturn($form);
+
+ $form->isSubmitted()->willReturn(true);
+ $form->isValid()->willReturn(true);
+
+ $form->getData()->willReturn(new \stdClass());
+
+ $this->expectException(\InvalidArgumentException::class);
+
+ $provider->provideFromOldOrderAndRequest($order, $request);
+ }
+}
|