diff --git a/src/Components/AmazonPay/EventListener/CheckoutCartEventListener.php b/src/Components/AmazonPay/EventListener/CheckoutCartEventListener.php index f6ecf1cf..8fb17d51 100644 --- a/src/Components/AmazonPay/EventListener/CheckoutCartEventListener.php +++ b/src/Components/AmazonPay/EventListener/CheckoutCartEventListener.php @@ -69,11 +69,13 @@ public function onCartLoaded(CheckoutCartPageLoadedEvent|OffcanvasCartPageLoaded return; } - $filteredPaymentMethods = $this->paymentFilterService->filterPaymentMethods( - new PaymentMethodCollection([(new PaymentMethodEntity())->assign([ - 'id' => PayoneAmazonPayExpress::UUID, - 'handlerIdentifier' => PayoneAmazonPayExpressPaymentHandler::class, - ])]), + $paymentMethods = new PaymentMethodCollection([(new PaymentMethodEntity())->assign([ + 'id' => PayoneAmazonPayExpress::UUID, + 'handlerIdentifier' => PayoneAmazonPayExpressPaymentHandler::class, + ])]); + + $this->paymentFilterService->filterPaymentMethods( + $paymentMethods, new PaymentFilterContext( salesChannelContext: $event->getSalesChannelContext(), currency: $event->getSalesChannelContext()->getCurrency(), @@ -84,7 +86,7 @@ public function onCartLoaded(CheckoutCartPageLoadedEvent|OffcanvasCartPageLoaded ) ); - if (!$filteredPaymentMethods->has(PayoneAmazonPayExpress::UUID)) { + if (!$paymentMethods->has(PayoneAmazonPayExpress::UUID)) { return; } diff --git a/src/Components/PaymentFilter/DefaultPaymentFilterService.php b/src/Components/PaymentFilter/DefaultPaymentFilterService.php index 646cb690..b5dded16 100644 --- a/src/Components/PaymentFilter/DefaultPaymentFilterService.php +++ b/src/Components/PaymentFilter/DefaultPaymentFilterService.php @@ -36,10 +36,10 @@ public function __construct( final public function filterPaymentMethods( PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext - ): PaymentMethodCollection { + ): void { $supportedPaymentMethods = $this->getSupportedPaymentMethods($methodCollection); if ($supportedPaymentMethods->getElements() === []) { - return $methodCollection; + return; } $currency = $filterContext->getCurrency(); @@ -70,10 +70,8 @@ final public function filterPaymentMethods( $this->additionalChecks($methodCollection, $filterContext); } catch (PaymentMethodNotAllowedException $paymentMethodNotAllowedException) { - $methodCollection = $this->removePaymentMethods($methodCollection, $paymentMethodNotAllowedException->getDisallowedPaymentMethodCollection()); + $this->removePaymentMethods($methodCollection, $paymentMethodNotAllowedException->getDisallowedPaymentMethodCollection()); } - - return $methodCollection; } protected function additionalChecks( @@ -91,11 +89,13 @@ private function getSupportedPaymentMethods(PaymentMethodCollection $paymentMeth : $paymentMethod->getHandlerIdentifier() === $this->paymentHandlerClass); } - private function removePaymentMethods(PaymentMethodCollection $paymentMethodCollection, ?PaymentMethodCollection $itemsToRemove = null): PaymentMethodCollection + private function removePaymentMethods(PaymentMethodCollection $paymentMethodCollection, ?PaymentMethodCollection $itemsToRemove = null): void { $itemsToRemove = $itemsToRemove ?: $this->getSupportedPaymentMethods($paymentMethodCollection); - return $paymentMethodCollection->filter(static fn (PaymentMethodEntity $entity) => !$itemsToRemove->has($entity->getUniqueIdentifier())); + foreach ($itemsToRemove->getIds() as $id) { + $paymentMethodCollection->remove($id); + } } private function validateAddress(CustomerAddressEntity|OrderAddressEntity|null $address): void diff --git a/src/Components/PaymentFilter/FilteredPaymentMethodRoute.php b/src/Components/PaymentFilter/FilteredPaymentMethodRoute.php index c8b51e03..0b45edff 100644 --- a/src/Components/PaymentFilter/FilteredPaymentMethodRoute.php +++ b/src/Components/PaymentFilter/FilteredPaymentMethodRoute.php @@ -41,34 +41,23 @@ public function load(Request $request, SalesChannelContext $context, Criteria $c $response = $this->getDecorated()->load($request, $context, $criteria); $currentRequest = $this->requestStack->getCurrentRequest(); - if (!$currentRequest) { - return $response; - } - if ($request->query->getBoolean('onlyAvailable') || $request->request->getBoolean('onlyAvailable')) { - $orderId = $currentRequest->get('orderId'); - if ($orderId) { - $order = $this->orderFetcher->getOrderById($orderId, $context->getContext()); - if (!$order) { - throw new \RuntimeException('order not found!'); - } - $filterContext = $this->paymentFilterContextFactory->createContextForOrder($order, $context); - } else { - $filterContext = $this->paymentFilterContextFactory->createContextForCart( - $this->cartService->getCart($context->getToken(), $context), - $context - ); + $orderId = $currentRequest?->get('orderId'); + if ($orderId) { + $order = $this->orderFetcher->getOrderById($orderId, $context->getContext()); + if (!$order) { + throw new \RuntimeException('order not found!'); } - - $paymentMethods = $response->getPaymentMethods(); - - $paymentMethods = $this->iterablePaymentFilter->filterPaymentMethods($paymentMethods, $filterContext); - - $criteria->setIds($paymentMethods->getIds()); - - return $this->getDecorated()->load($request, $context, $criteria); + $filterContext = $this->paymentFilterContextFactory->createContextForOrder($order, $context); + } else { + $filterContext = $this->paymentFilterContextFactory->createContextForCart( + $this->cartService->getCart($context->getToken(), $context), + $context + ); } + $this->iterablePaymentFilter->filterPaymentMethods($response->getPaymentMethods(), $filterContext); + return $response; } } diff --git a/src/Components/PaymentFilter/GenericExpressCheckoutFilterOther.php b/src/Components/PaymentFilter/GenericExpressCheckoutFilterOther.php index 7e4114b5..063e1904 100644 --- a/src/Components/PaymentFilter/GenericExpressCheckoutFilterOther.php +++ b/src/Components/PaymentFilter/GenericExpressCheckoutFilterOther.php @@ -12,16 +12,17 @@ class GenericExpressCheckoutFilterOther implements PaymentFilterServiceInterface /** * if AmazonPay/PayPal Express is selected, no other payment methods should be available. */ - public function filterPaymentMethods(PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext): PaymentMethodCollection + public function filterPaymentMethods(PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext): void { $actualPaymentMethod = $filterContext->getSalesChannelContext()->getPaymentMethod(); if ($methodCollection->has($actualPaymentMethod->getId()) && \in_array($actualPaymentMethod->getHandlerIdentifier(), PaymentHandlerGroups::GENERIC_EXPRESS, true) ) { - return new PaymentMethodCollection([$actualPaymentMethod]); + $idsToRemove = array_filter($methodCollection->getIds(), static fn (string $id): bool => $id !== $actualPaymentMethod->getId()); + foreach ($idsToRemove as $id) { + $methodCollection->remove($id); + } } - - return $methodCollection; } } diff --git a/src/Components/PaymentFilter/IterablePaymentFilter.php b/src/Components/PaymentFilter/IterablePaymentFilter.php index cb13708a..47a268d3 100644 --- a/src/Components/PaymentFilter/IterablePaymentFilter.php +++ b/src/Components/PaymentFilter/IterablePaymentFilter.php @@ -16,11 +16,9 @@ public function __construct(private readonly iterable $services) public function filterPaymentMethods( PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext - ): PaymentMethodCollection { + ): void { foreach ($this->services as $service) { - $methodCollection = $service->filterPaymentMethods($methodCollection, $filterContext); + $service->filterPaymentMethods($methodCollection, $filterContext); } - - return $methodCollection; } } diff --git a/src/Components/PaymentFilter/PaymentFilterServiceInterface.php b/src/Components/PaymentFilter/PaymentFilterServiceInterface.php index 726616e7..7dc34724 100644 --- a/src/Components/PaymentFilter/PaymentFilterServiceInterface.php +++ b/src/Components/PaymentFilter/PaymentFilterServiceInterface.php @@ -9,5 +9,5 @@ interface PaymentFilterServiceInterface public function filterPaymentMethods( PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext - ): PaymentMethodCollection; + ): void; } diff --git a/src/Components/PaymentFilter/PayonePaymentMethodValidator.php b/src/Components/PaymentFilter/PayonePaymentMethodValidator.php index faaf1179..68b82229 100644 --- a/src/Components/PaymentFilter/PayonePaymentMethodValidator.php +++ b/src/Components/PaymentFilter/PayonePaymentMethodValidator.php @@ -27,7 +27,7 @@ public function validate(Cart $cart, ErrorCollection $errors, SalesChannelContex $filterContext = $this->paymentFilterContextFactory->createContextForCart($cart, $context); - $paymentMethods = $this->iterablePaymentFilter->filterPaymentMethods($paymentMethods, $filterContext); + $this->iterablePaymentFilter->filterPaymentMethods($paymentMethods, $filterContext); if ($paymentMethods->count() === 0) { $errors->add( diff --git a/src/Components/PaymentFilter/TotalPriceFilter.php b/src/Components/PaymentFilter/TotalPriceFilter.php index 2cd26957..1bb32021 100644 --- a/src/Components/PaymentFilter/TotalPriceFilter.php +++ b/src/Components/PaymentFilter/TotalPriceFilter.php @@ -11,19 +11,20 @@ class TotalPriceFilter implements PaymentFilterServiceInterface public function filterPaymentMethods( PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext - ): PaymentMethodCollection { + ): void { if ($filterContext->getOrder()) { $price = $filterContext->getOrder()->getPrice()->getTotalPrice(); } elseif ($filterContext->getCart()) { $price = $filterContext->getCart()->getPrice()->getTotalPrice(); } else { - return $methodCollection; + return; } if ($price <= 0) { - return $methodCollection->filter(static fn (PaymentMethodEntity $entity) => !is_subclass_of($entity->getHandlerIdentifier(), AbstractPayonePaymentHandler::class)); + $idsToRemove = $methodCollection->filter(static fn (PaymentMethodEntity $entity) => is_subclass_of($entity->getHandlerIdentifier(), AbstractPayonePaymentHandler::class))->getIds(); + foreach ($idsToRemove as $id) { + $methodCollection->remove($id); + } } - - return $methodCollection; } } diff --git a/tests/Components/PaymentFilter/AbstractPaymentFilterTest.php b/tests/Components/PaymentFilter/AbstractPaymentFilterTest.php index 3a766035..2dab3218 100644 --- a/tests/Components/PaymentFilter/AbstractPaymentFilterTest.php +++ b/tests/Components/PaymentFilter/AbstractPaymentFilterTest.php @@ -48,10 +48,10 @@ public function testItHidesPaymentMethodForNotAllowedCountry(string $paymentHand $this->getAllowedCurrency() ); - $result = $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); + $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); - static::assertNotInPaymentCollection($paymentHandlerClass, $result); - static::assertInPaymentCollection(PaymentHandlerMock::class, $result); + static::assertNotInPaymentCollection($paymentHandlerClass, $methods); + static::assertInPaymentCollection(PaymentHandlerMock::class, $methods); } /** @@ -80,10 +80,10 @@ public function testItHidesPaymentMethodForNotAllowedCurrency(string $paymentHan $this->getDisallowedCurrency() ); - $result = $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); + $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); - static::assertNotInPaymentCollection($paymentHandlerClass, $result); - static::assertInPaymentCollection(PaymentHandlerMock::class, $result); + static::assertNotInPaymentCollection($paymentHandlerClass, $methods); + static::assertInPaymentCollection(PaymentHandlerMock::class, $methods); } /** @@ -117,10 +117,10 @@ public function testItHidesPaymentMethodForNotAllowedValueOnCheckout(float $notA $cart ); - $result = $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); + $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); - static::assertNotInPaymentCollection($paymentHandlerClass, $result); - static::assertInPaymentCollection(PaymentHandlerMock::class, $result); + static::assertNotInPaymentCollection($paymentHandlerClass, $methods); + static::assertInPaymentCollection(PaymentHandlerMock::class, $methods); } /** @@ -152,10 +152,10 @@ public function testItHidesPaymentMethodForNotAllowedValueOnEditOrderPage(float $order ); - $result = $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); + $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); - static::assertNotInPaymentCollection($paymentHandlerClass, $result); - static::assertInPaymentCollection(PaymentHandlerMock::class, $result); + static::assertNotInPaymentCollection($paymentHandlerClass, $methods); + static::assertInPaymentCollection(PaymentHandlerMock::class, $methods); } /** @@ -186,10 +186,10 @@ public function testItNotHidesPaymentMethodForAllowedConditionsOnCheckout(string $cart ); - $result = $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); + $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); - static::assertInPaymentCollection($paymentHandlerClass, $result); - static::assertInPaymentCollection(PaymentHandlerMock::class, $result); + static::assertInPaymentCollection($paymentHandlerClass, $methods); + static::assertInPaymentCollection(PaymentHandlerMock::class, $methods); } /** @@ -219,10 +219,10 @@ public function testItNotHidesPaymentMethodForAllowedConditionsOnEditOrderPage(s $order ); - $result = $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); + $this->getFilterService($paymentHandlerClass)->filterPaymentMethods($methods, $filterContext); - static::assertInPaymentCollection($paymentHandlerClass, $result); - static::assertInPaymentCollection(PaymentHandlerMock::class, $result); + static::assertInPaymentCollection($paymentHandlerClass, $methods); + static::assertInPaymentCollection(PaymentHandlerMock::class, $methods); } public function notAllowedValues(): \Generator diff --git a/tests/Components/PaymentFilter/DefaultPaymentFilterServiceTest.php b/tests/Components/PaymentFilter/DefaultPaymentFilterServiceTest.php index e6ed1ee7..b1eff850 100644 --- a/tests/Components/PaymentFilter/DefaultPaymentFilterServiceTest.php +++ b/tests/Components/PaymentFilter/DefaultPaymentFilterServiceTest.php @@ -57,30 +57,28 @@ public function testCurrency(): void $systemConfigService = $this->createMock(SystemConfigService::class); $filterService = new DefaultPaymentFilterService($systemConfigService, PaymentHandlerMock::class, ['DE'], null, ['EUR']); - $result = $filterService->filterPaymentMethods($methodCollection, $chfFilterContext); - static::assertCount(2, $result->getElements(), 'first payment method should be removed, cause service should only process first payment method, and the currency is not allowed'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $chfFilterContext); + static::assertCount(2, $collection->getElements(), 'first payment method should be removed, cause service should only process first payment method, and the currency is not allowed'); $filterService = new DefaultPaymentFilterService($systemConfigService, \stdClass::class, ['DE'], null, ['EUR']); - $result = $filterService->filterPaymentMethods($methodCollection, $chfFilterContext); - static::assertCount(1, $result->getElements(), 'second and third payment method should be removed, cause service should only process second/third payment method, and the currency is not allowed'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $chfFilterContext); + static::assertCount(1, $collection->getElements(), 'second and third payment method should be removed, cause service should only process second/third payment method, and the currency is not allowed'); $filterService = new DefaultPaymentFilterService($systemConfigService, PaymentHandlerMock::class, ['DE'], null, ['EUR']); - $result = $filterService->filterPaymentMethods($methodCollection, $euroFilterContext); - static::assertCount(3, $result->getElements(), 'no payment method should be removed, cause the currency is allowed for the first method'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $euroFilterContext); + static::assertCount(3, $collection->getElements(), 'no payment method should be removed, cause the currency is allowed for the first method'); $filterService = new DefaultPaymentFilterService($systemConfigService, \stdClass::class, ['DE'], null, ['EUR']); - $result = $filterService->filterPaymentMethods($methodCollection, $euroFilterContext); - static::assertCount(3, $result->getElements(), 'no payment method should be removed, cause the currency is allowed for the second and the method'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $euroFilterContext); + static::assertCount(3, $collection->getElements(), 'no payment method should be removed, cause the currency is allowed for the second and the method'); $filterService = new DefaultPaymentFilterService($systemConfigService, \stdClass::class, ['DE'], null, null); - $result = $filterService->filterPaymentMethods($methodCollection, $euroFilterContext); - static::assertCount(3, $result->getElements(), 'no payment method should be removed, cause no currency filter is provided'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $euroFilterContext); + static::assertCount(3, $collection->getElements(), 'no payment method should be removed, cause no currency filter is provided'); } public function testB2C(): void { - $methodCollection = $this->getMethodCollection(); - $salesChannelContext = $this->createSalesChannelContextWithLoggedInCustomerAndWithNavigation(); $billingAddress = $salesChannelContext->getCustomer()->getActiveBillingAddress(); @@ -100,38 +98,36 @@ public function testB2C(): void $billingAddress->getCountry()->setIso('DE'); $filterService = new DefaultPaymentFilterService($systemConfigService, PaymentHandlerMock::class, ['FR'], null, null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(2, $result->getElements(), 'first payment method should be removed, cause service should only process first payment method, and the country is not allowed'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertCount(2, $collection->getElements(), 'first payment method should be removed, cause service should only process first payment method, and the country is not allowed'); $billingAddress->getCountry()->setIso('DE'); $filterService = new DefaultPaymentFilterService($systemConfigService, \stdClass::class, ['FR'], null, null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(1, $result->getElements(), 'second and third payment method should be removed, cause service should only process second/third payment method, and the country is not allowed'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertCount(1, $collection->getElements(), 'second and third payment method should be removed, cause service should only process second/third payment method, and the country is not allowed'); $billingAddress->getCountry()->setIso('FR'); $filterService = new DefaultPaymentFilterService($systemConfigService, PaymentHandlerMock::class, ['FR'], null, null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(3, $result->getElements(), 'no payment method should be removed, cause the country is allowed for the first method'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertCount(3, $collection->getElements(), 'no payment method should be removed, cause the country is allowed for the first method'); $billingAddress->getCountry()->setIso('FR'); $filterService = new DefaultPaymentFilterService($systemConfigService, \stdClass::class, ['FR'], null, null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(3, $result->getElements(), 'no payment method should be removed, cause the country is allowed for the second and the method'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertCount(3, $collection->getElements(), 'no payment method should be removed, cause the country is allowed for the second and the method'); $filterService = new DefaultPaymentFilterService($systemConfigService, \stdClass::class, null, null, null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(3, $result->getElements(), 'no payment method should be removed, cause no country filter is provided'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertCount(3, $collection->getElements(), 'no payment method should be removed, cause no country filter is provided'); $billingAddress->getCountry()->setIso('FR'); $filterService = new DefaultPaymentFilterService($systemConfigService, \stdClass::class, [], ['FR'], null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertNotContainsOnly(\stdClass::class, $result->getElements(), false, 'payment method stdclass should be removed, because country FR is only allowed for B2B customers and not B2C customers.'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertNotContainsOnly(\stdClass::class, $collection->getElements(), false, 'payment method stdclass should be removed, because country FR is only allowed for B2B customers and not B2C customers.'); } public function testB2B(): void { - $methodCollection = $this->getMethodCollection(); - $salesChannelContext = $this->createSalesChannelContextWithLoggedInCustomerAndWithNavigation(); $billingAddress = $salesChannelContext->getCustomer()->getActiveBillingAddress(); @@ -152,32 +148,32 @@ public function testB2B(): void $billingAddress->getCountry()->setIso('DE'); $filterService = new DefaultPaymentFilterService($systemConfigService, PaymentHandlerMock::class, null, ['FR'], null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(2, $result->getElements(), 'first payment method should be removed, cause service should only process first payment method, and the country is not allowed'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertCount(2, $collection->getElements(), 'first payment method should be removed, cause service should only process first payment method, and the country is not allowed'); $billingAddress->getCountry()->setIso('DE'); $filterService = new DefaultPaymentFilterService($systemConfigService, \stdClass::class, null, ['FR'], null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(1, $result->getElements(), 'second and third payment method should be removed, cause service should only process second/third payment method, and the country is not allowed'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertCount(1, $collection->getElements(), 'second and third payment method should be removed, cause service should only process second/third payment method, and the country is not allowed'); $billingAddress->getCountry()->setIso('FR'); $filterService = new DefaultPaymentFilterService($systemConfigService, PaymentHandlerMock::class, null, ['FR'], null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(3, $result->getElements(), 'no payment method should be removed, cause the country is allowed for the first method'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertCount(3, $collection->getElements(), 'no payment method should be removed, cause the country is allowed for the first method'); $billingAddress->getCountry()->setIso('FR'); $filterService = new DefaultPaymentFilterService($systemConfigService, \stdClass::class, null, ['FR'], null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(3, $result->getElements(), 'no payment method should be removed, cause the country is allowed for the second and th method'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertCount(3, $collection->getElements(), 'no payment method should be removed, cause the country is allowed for the second and th method'); $filterService = new DefaultPaymentFilterService($systemConfigService, \stdClass::class, null, null, null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(3, $result->getElements(), 'no payment method should be removed, cause no country filter is provided'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertCount(3, $collection->getElements(), 'no payment method should be removed, cause no country filter is provided'); $billingAddress->getCountry()->setIso('FR'); $filterService = new DefaultPaymentFilterService($systemConfigService, \stdClass::class, ['FR'], [], null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertNotContainsOnly(\stdClass::class, $result->getElements(), false, 'payment method stdclass should be removed, because country FR is only allowed for B2C customers and not B2B customers.'); + $filterService->filterPaymentMethods($collection = $this->getMethodCollection(), $filterContext); + static::assertNotContainsOnly(\stdClass::class, $collection->getElements(), false, 'payment method stdclass should be removed, because country FR is only allowed for B2C customers and not B2B customers.'); } public function testDifferentShippingAddress(): void @@ -186,9 +182,6 @@ public function testDifferentShippingAddress(): void $method->setUniqueIdentifier(Uuid::randomHex()); $method->setHandlerIdentifier(PayoneSecuredInvoicePaymentHandler::class); - $methodCollection = $this->getMethodCollection(); - $methodCollection->add($method); - $salesChannelContext = $this->createSalesChannelContextWithLoggedInCustomerAndWithNavigation(); $differentShippingAddress = new CustomerAddressEntity(); @@ -223,8 +216,10 @@ public function testDifferentShippingAddress(): void ; $filterService = new DefaultPaymentFilterService($systemConfigService, PayoneSecuredInvoicePaymentHandler::class, null, null, null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(4, $result->getElements(), 'no payment method should be removed, because no configuration exists'); + $methodCollection = $this->getMethodCollection(); + $methodCollection->add($method); + $filterService->filterPaymentMethods($methodCollection, $filterContext); + static::assertCount(4, $methodCollection->getElements(), 'no payment method should be removed, because no configuration exists'); $systemConfigService = $this->createMock(SystemConfigService::class); $systemConfigService @@ -238,8 +233,10 @@ public function testDifferentShippingAddress(): void ; $filterService = new DefaultPaymentFilterService($systemConfigService, PayoneSecuredInvoicePaymentHandler::class, null, null, null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(4, $result->getElements(), 'no payment method should be removed, because a different shipping address is allowed'); + $methodCollection = $this->getMethodCollection(); + $methodCollection->add($method); + $filterService->filterPaymentMethods($methodCollection, $filterContext); + static::assertCount(4, $methodCollection->getElements(), 'no payment method should be removed, because a different shipping address is allowed'); $systemConfigService = $this->createMock(SystemConfigService::class); $systemConfigService @@ -253,8 +250,10 @@ public function testDifferentShippingAddress(): void ; $filterService = new DefaultPaymentFilterService($systemConfigService, PayoneSecuredInvoicePaymentHandler::class, null, null, null); - $result = $filterService->filterPaymentMethods($methodCollection, $filterContext); - static::assertCount(3, $result->getElements(), 'payment method should be removed, because a different shipping address is not allowed'); + $methodCollection = $this->getMethodCollection(); + $methodCollection->add($method); + $filterService->filterPaymentMethods($methodCollection, $filterContext); + static::assertCount(3, $methodCollection->getElements(), 'payment method should be removed, because a different shipping address is not allowed'); } private function getMethodCollection(): PaymentMethodCollection diff --git a/tests/Components/PaymentFilter/FilteredPaymentMethodRouteTest.php b/tests/Components/PaymentFilter/FilteredPaymentMethodRouteTest.php new file mode 100644 index 00000000..f35a3313 --- /dev/null +++ b/tests/Components/PaymentFilter/FilteredPaymentMethodRouteTest.php @@ -0,0 +1,117 @@ +createMock(AbstractPaymentMethodRoute::class); + $decorated->method('load')->willReturn($this->getDefaultResponse($ids, true)); + + $filter = $this->getFilterService($ids); + + $route = new FilteredPaymentMethodRoute( + $decorated, + $filter, + new RequestStack(), + $this->createMock(OrderFetcherInterface::class), + $this->getContainer()->get(CartService::class), + $this->getContainer()->get(PaymentFilterContextFactoryInterface::class) + ); + + $response = $route->load(new Request(), $this->createSalesChannelContext(), new Criteria()); + static::assertEquals(1, $response->getPaymentMethods()->count()); + static::assertEquals(stdClass::class, $response->getPaymentMethods()->first()->getHandlerIdentifier()); + } + + public function testIfServiceWontCrashOnEmptyMethods(): void + { + $ids = [Uuid::randomHex(), Uuid::randomHex()]; + $decorated = $this->createMock(AbstractPaymentMethodRoute::class); + $decorated->method('load')->willReturn($this->getDefaultResponse([], false)); + + $filter = $this->getFilterService($ids); + + $route = new FilteredPaymentMethodRoute( + $decorated, + $filter, + new RequestStack(), + $this->createMock(OrderFetcherInterface::class), + $this->getContainer()->get(CartService::class), + $this->getContainer()->get(PaymentFilterContextFactoryInterface::class) + ); + + $response = $route->load(new Request(), $this->createSalesChannelContext(), new Criteria()); + static::assertEquals(0, $response->getPaymentMethods()->count()); + } + + private function getFilterService(array $ids): IterablePaymentFilter + { + return new class($ids) extends IterablePaymentFilter { + /** + * @noinspection PhpMissingParentConstructorInspection + */ + public function __construct( + private readonly array $idsToRemove + ) { + } + + public function filterPaymentMethods(PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext): void + { + foreach ($this->idsToRemove as $id) { + $methodCollection->remove($id); + } + } + }; + } + + private function getDefaultResponse(array $payoneMethodIds, bool $addStd): PaymentMethodRouteResponse + { + $methods = []; + foreach ($payoneMethodIds as $id) { + $paymentMethod = new PaymentMethodEntity(); + $paymentMethod->setId($id); + $paymentMethod->setHandlerIdentifier(PaymentHandlerMock::class); + $methods[] = $paymentMethod; + } + if ($addStd) { + $paymentMethod2 = new PaymentMethodEntity(); + $paymentMethod2->setId(Uuid::randomHex()); + $paymentMethod2->setHandlerIdentifier(stdClass::class); + $methods[] = $paymentMethod2; + } + + $entitySearchResult = new EntitySearchResult( + 'payment_method', + \count($methods), + new PaymentMethodCollection($methods), + null, + new Criteria(), + Context::createDefaultContext() + ); + + return new PaymentMethodRouteResponse($entitySearchResult); + } +} diff --git a/tests/Components/PaymentFilter/PayolutionPaymentFilterTest.php b/tests/Components/PaymentFilter/PayolutionPaymentFilterTest.php index 8252dc18..0398bd79 100644 --- a/tests/Components/PaymentFilter/PayolutionPaymentFilterTest.php +++ b/tests/Components/PaymentFilter/PayolutionPaymentFilterTest.php @@ -31,23 +31,23 @@ public function testIfInvoiceGotHiddenOnDisabledB2B(): void { $this->setPayoneConfig($this->getContainer(), 'payolutionInvoicingTransferCompanyData', false); - $methods = $this->getPaymentMethods(PayonePayolutionInvoicingPaymentHandler::class); - $salesChannelContext = $this->createSalesChannelContextWithLoggedInCustomerAndWithNavigation(); $salesChannelContext->getCustomer()->getActiveBillingAddress()->setCompany('not-empty'); $filterContext = new PaymentFilterContext($salesChannelContext, $salesChannelContext->getCustomer()->getActiveBillingAddress()); $filterService = $this->getFilterService(PayonePayolutionInvoicingPaymentHandler::class); - $result = $filterService->filterPaymentMethods($methods, $filterContext); - static::assertNotInPaymentCollection(PayonePayolutionInvoicingPaymentHandler::class, $result, 'unzer invoice should be removed, because B2B is not allowed'); - static::assertInPaymentCollection(PaymentHandlerMock::class, $result, 'the PaymentHandlerMock should be never removed from the available payment-methods'); + $methods = $this->getPaymentMethods(PayonePayolutionInvoicingPaymentHandler::class); + $filterService->filterPaymentMethods($methods, $filterContext); + static::assertNotInPaymentCollection(PayonePayolutionInvoicingPaymentHandler::class, $methods, 'unzer invoice should be removed, because B2B is not allowed'); + static::assertInPaymentCollection(PaymentHandlerMock::class, $methods, 'the PaymentHandlerMock should be never removed from the available payment-methods'); // test again, but now the payment method should be available, because we allow B2B $this->setPayoneConfig($this->getContainer(), 'payolutionInvoicingTransferCompanyData', true); - $result = $filterService->filterPaymentMethods($methods, $filterContext); - static::assertInPaymentCollection(PayonePayolutionInvoicingPaymentHandler::class, $result, 'after enabling the B2B for invoice, the payment method should be available'); - static::assertInPaymentCollection(PaymentHandlerMock::class, $result, 'the PaymentHandlerMock should be never removed from the available payment-methods'); + $methods = $this->getPaymentMethods(PayonePayolutionInvoicingPaymentHandler::class); + $filterService->filterPaymentMethods($methods, $filterContext); + static::assertInPaymentCollection(PayonePayolutionInvoicingPaymentHandler::class, $methods, 'after enabling the B2B for invoice, the payment method should be available'); + static::assertInPaymentCollection(PaymentHandlerMock::class, $methods, 'the PaymentHandlerMock should be never removed from the available payment-methods'); } /** @@ -66,9 +66,9 @@ public function testIfUnzerGotHiddenOnB2B(string $paymentHandler): void $filterContext = new PaymentFilterContext($salesChannelContext, $salesChannelContext->getCustomer()->getActiveBillingAddress()); $filterService = $this->getFilterService($paymentHandler); - $result = $filterService->filterPaymentMethods($methods, $filterContext); - static::assertNotInPaymentCollection($paymentHandler, $result, $paymentHandler . ' should be removed, because B2B is not allowed'); - static::assertInPaymentCollection(PaymentHandlerMock::class, $result, 'the PaymentHandlerMock should be never removed from the available payment-methods'); + $filterService->filterPaymentMethods($methods, $filterContext); + static::assertNotInPaymentCollection($paymentHandler, $methods, $paymentHandler . ' should be removed, because B2B is not allowed'); + static::assertInPaymentCollection(PaymentHandlerMock::class, $methods, 'the PaymentHandlerMock should be never removed from the available payment-methods'); } public static function dataProviderUnzerGotHiddenOnB2B(): array @@ -95,14 +95,14 @@ public function testIfUnzerIsAlwaysAvailableForOnB2C(string $paymentHandler): vo $filterService = $this->getFilterService($paymentHandler); $this->setPayoneConfig($this->getContainer(), 'payolutionInvoicingTransferCompanyData', false); - $result = $filterService->filterPaymentMethods($methods, $filterContext); - static::assertInPaymentCollection($paymentHandler, $result); - static::assertInPaymentCollection(PaymentHandlerMock::class, $result); + $filterService->filterPaymentMethods($methods, $filterContext); + static::assertInPaymentCollection($paymentHandler, $methods); + static::assertInPaymentCollection(PaymentHandlerMock::class, $methods); $this->setPayoneConfig($this->getContainer(), 'payolutionInvoicingTransferCompanyData', true); - $result = $filterService->filterPaymentMethods($methods, $filterContext); - static::assertInPaymentCollection($paymentHandler, $result); - static::assertInPaymentCollection(PaymentHandlerMock::class, $result); + $filterService->filterPaymentMethods($methods, $filterContext); + static::assertInPaymentCollection($paymentHandler, $methods); + static::assertInPaymentCollection(PaymentHandlerMock::class, $methods); } public static function dataProviderUnzerIsAlwaysAvailableForOnB2C(): array diff --git a/tests/Components/PaymentFilter/TotalPriceFilterTest.php b/tests/Components/PaymentFilter/TotalPriceFilterTest.php index 292962ac..804ec710 100644 --- a/tests/Components/PaymentFilter/TotalPriceFilterTest.php +++ b/tests/Components/PaymentFilter/TotalPriceFilterTest.php @@ -38,13 +38,13 @@ public function testIfRemovesAllMethodsIfPriceEqualZeroForCart(): void ); $cartMock->method('getPrice')->willReturn($this->createPrice(0)); - $collection = $filter->filterPaymentMethods($this->getMethodCollection(), $context); + $filter->filterPaymentMethods($collection = $this->getMethodCollection(), $context); static::assertCount(3, $collection->getElements()); static::assertPaymentMethodCount(3, DefaultPayment::class, $collection); static::assertPaymentMethodCount(0, PayonePrepaymentPaymentHandler::class, $collection); $cartMock->method('getPrice')->willReturn($this->createPrice(-100)); - $collection = $filter->filterPaymentMethods($this->getMethodCollection(), $context); + $filter->filterPaymentMethods($collection = $this->getMethodCollection(), $context); static::assertCount(3, $collection->getElements()); static::assertPaymentMethodCount(3, DefaultPayment::class, $collection); static::assertPaymentMethodCount(0, PayonePrepaymentPaymentHandler::class, $collection); @@ -64,13 +64,13 @@ public function testIfRemovesAllMethodsIfPriceEqualZeroForOrder(): void ); $cartMock->method('getPrice')->willReturn($this->createPrice(0)); - $collection = $filter->filterPaymentMethods($this->getMethodCollection(), $context); + $filter->filterPaymentMethods($collection = $this->getMethodCollection(), $context); static::assertCount(3, $collection->getElements()); static::assertPaymentMethodCount(3, DefaultPayment::class, $collection); static::assertPaymentMethodCount(0, PayonePrepaymentPaymentHandler::class, $collection); $cartMock->method('getPrice')->willReturn($this->createPrice(-100)); - $collection = $filter->filterPaymentMethods($this->getMethodCollection(), $context); + $filter->filterPaymentMethods($collection = $this->getMethodCollection(), $context); static::assertCount(3, $collection->getElements()); static::assertPaymentMethodCount(3, DefaultPayment::class, $collection); static::assertPaymentMethodCount(0, PayonePrepaymentPaymentHandler::class, $collection); @@ -90,7 +90,7 @@ public function testIfKeepsAllMethodsIfPriceHigherZeroForCart(): void $orderMock->method('getPrice')->willReturn($this->createPrice(100)); - $collection = $filter->filterPaymentMethods($this->getMethodCollection(), $context); + $filter->filterPaymentMethods($collection = $this->getMethodCollection(), $context); static::assertCount(6, $collection->getElements()); static::assertPaymentMethodCount(3, DefaultPayment::class, $collection); static::assertPaymentMethodCount(3, PayonePrepaymentPaymentHandler::class, $collection); @@ -110,7 +110,7 @@ public function testIfRemovesAllMethodsIfPriceHigherZeroForOrder(): void $orderMock->method('getPrice')->willReturn($this->createPrice(100)); - $collection = $filter->filterPaymentMethods($this->getMethodCollection(), $context); + $filter->filterPaymentMethods($collection = $this->getMethodCollection(), $context); static::assertCount(6, $collection->getElements()); static::assertPaymentMethodCount(3, DefaultPayment::class, $collection); static::assertPaymentMethodCount(3, PayonePrepaymentPaymentHandler::class, $collection);