-
Notifications
You must be signed in to change notification settings - Fork 9.4k
#40235 - Conditionally process collectTotal for CartItemPrices GraphQl based on params in the request #40289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 2.4-develop
Are you sure you want to change the base?
Changes from all commits
fddd1b6
b352228
ae4d79f
8e7681a
a15df22
f4f87f8
1d3f9ef
0b047b9
099bb97
b216034
18095f9
86092fa
50e9916
ae280b8
ad6f4d6
b7d0fcc
3757e5a
988ae59
45a4894
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,215 @@ | ||
| <?php | ||
| /** | ||
| * Copyright 2024 Adobe | ||
| * All Rights Reserved. | ||
| */ | ||
| declare(strict_types=1); | ||
|
|
||
| namespace Magento\QuoteGraphQl\Test\Unit\Model\Resolver; | ||
|
|
||
| use Magento\Framework\Exception\LocalizedException; | ||
| use Magento\Framework\GraphQl\Config\Element\Field; | ||
| use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; | ||
| use Magento\GraphQl\Model\Query\Context; | ||
| use Magento\Quote\Model\Quote; | ||
| use Magento\Quote\Model\Quote\Item; | ||
| use Magento\QuoteGraphQl\Model\Cart\TotalsCollector; | ||
| use Magento\QuoteGraphQl\Model\Resolver\CartItemPrices; | ||
| use Magento\QuoteGraphQl\Model\GetDiscounts; | ||
| use Magento\Framework\Pricing\PriceCurrencyInterface; | ||
| use Magento\QuoteGraphQl\Model\GetOptionsRegularPrice; | ||
| use Magento\Framework\Api\ExtensionAttributesInterface; | ||
| use Magento\Catalog\Model\Product; | ||
| use PHPUnit\Framework\TestCase; | ||
| use PHPUnit\Framework\MockObject\MockObject; | ||
|
|
||
| /** | ||
| * @see CartItemPrices | ||
| * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||
| */ | ||
| class CartItemPricesTest extends TestCase | ||
| { | ||
| /** | ||
| * @var CartItemPrices | ||
| */ | ||
| private CartItemPrices $cartItemPrices; | ||
|
|
||
| /** | ||
| * @var TotalsCollector|MockObject | ||
| */ | ||
| private TotalsCollector $totalsCollectorMock; | ||
|
|
||
| /** | ||
| * @var GetDiscounts |MockObject | ||
| */ | ||
| private GetDiscounts $getDiscountsMock; | ||
|
|
||
| /** | ||
| * @var PriceCurrencyInterface |MockObject | ||
| */ | ||
| private PriceCurrencyInterface $priceCurrencyMock; | ||
|
|
||
| /** | ||
| * @var GetOptionsRegularPrice |MockObject | ||
| */ | ||
| private GetOptionsRegularPrice $getOptionsRegularPriceMock; | ||
|
|
||
| /** | ||
| * @var Field|MockObject | ||
| */ | ||
| private Field $fieldMock; | ||
|
|
||
| /** | ||
| * @var ResolveInfo|MockObject | ||
| */ | ||
| private ResolveInfo $resolveInfoMock; | ||
|
|
||
| /** | ||
| * @var Context|MockObject | ||
| */ | ||
| private Context $contextMock; | ||
|
|
||
| /** | ||
| * @var Quote|MockObject | ||
| */ | ||
| private Quote $quoteMock; | ||
|
|
||
| /** | ||
| * @var Item|MockObject | ||
| */ | ||
| private Item $itemMock; | ||
|
|
||
| /** | ||
| * @var Product|MockObject | ||
| */ | ||
| private Product $productMock; | ||
|
|
||
| /** | ||
| * @var ExtensionAttributesInterface|MockObject | ||
| */ | ||
| private ExtensionAttributesInterface $itemExtensionMock; | ||
|
|
||
| /** | ||
| * @var array | ||
| */ | ||
| private array $valueMock = []; | ||
|
|
||
| protected function setUp(): void | ||
| { | ||
| $this->totalsCollectorMock = $this->createMock(TotalsCollector::class); | ||
| $this->getDiscountsMock = $this->createMock(GetDiscounts::class); | ||
| $this->priceCurrencyMock = $this->createMock(PriceCurrencyInterface::class); | ||
| $this->getOptionsRegularPriceMock = $this->createMock(GetOptionsRegularPrice::class); | ||
| $this->productMock = $this->getMockBuilder(Product::class) | ||
| ->disableOriginalConstructor() | ||
| ->onlyMethods(['getCustomOption']) | ||
| ->getMock(); | ||
| $this->fieldMock = $this->createMock(Field::class); | ||
| $this->resolveInfoMock = $this->createMock(ResolveInfo::class); | ||
| $this->contextMock = $this->createMock(Context::class); | ||
| $this->quoteMock = $this->getMockBuilder(Quote::class) | ||
| ->disableOriginalConstructor() | ||
| ->addMethods(['getQuoteCurrencyCode']) | ||
| ->getMock(); | ||
| $this->itemMock = $this->getMockBuilder(Item::class) | ||
| ->addMethods([ | ||
| 'getPriceInclTax', 'getRowTotal', | ||
| 'getRowTotalInclTax', 'getDiscountAmount' | ||
| ]) | ||
| ->onlyMethods([ | ||
| 'getCalculationPrice', 'getQuote', 'getExtensionAttributes', | ||
| 'getProduct', 'getOriginalPrice' | ||
| ]) | ||
| ->disableOriginalConstructor() | ||
| ->getMock(); | ||
| $this->itemExtensionMock = $this->getMockBuilder( | ||
| ExtensionAttributesInterface::class | ||
| )->addMethods(['getDiscounts'])->getMockForAbstractClass(); | ||
|
|
||
| $this->cartItemPrices = new CartItemPrices( | ||
| $this->totalsCollectorMock, | ||
| $this->getDiscountsMock, | ||
| $this->priceCurrencyMock, | ||
| $this->getOptionsRegularPriceMock | ||
| ); | ||
| } | ||
|
|
||
| public function testResolve(): void | ||
| { | ||
| $this->valueMock = ['model' => $this->itemMock]; | ||
|
|
||
| $this->resolveInfoMock->expects($this->once()) | ||
| ->method('getFieldSelection') | ||
| ->with(1) | ||
| ->willReturn([]); | ||
|
|
||
| $this->itemMock | ||
| ->expects($this->exactly(2)) | ||
| ->method('getQuote') | ||
| ->willReturn($this->quoteMock); | ||
|
|
||
| $this->quoteMock | ||
| ->expects($this->once()) | ||
| ->method('getQuoteCurrencyCode') | ||
| ->willReturn('USD'); | ||
|
|
||
| $this->itemMock | ||
| ->expects($this->once()) | ||
| ->method('getDiscountAmount'); | ||
|
|
||
| $this->itemMock | ||
| ->expects($this->once()) | ||
| ->method('getCalculationPrice'); | ||
|
|
||
| $this->itemMock | ||
| ->expects($this->once()) | ||
| ->method('getPriceInclTax'); | ||
|
|
||
| $this->itemMock | ||
| ->expects($this->any()) | ||
| ->method('getOriginalPrice') | ||
| ->willReturn(0); | ||
|
|
||
| $this->itemMock | ||
| ->expects($this->once()) | ||
| ->method('getRowTotal'); | ||
|
|
||
| $this->itemMock | ||
| ->expects($this->once()) | ||
| ->method('getRowTotalInclTax'); | ||
|
|
||
| $this->itemMock | ||
| ->expects($this->once()) | ||
| ->method('getExtensionAttributes') | ||
| ->willReturn($this->itemExtensionMock); | ||
|
|
||
| $this->itemMock | ||
| ->expects($this->any()) | ||
| ->method('getProduct') | ||
| ->willReturn($this->productMock); | ||
|
|
||
| $this->productMock | ||
| ->expects($this->exactly(2)) | ||
| ->method('getCustomOption') | ||
| ->willReturn(null); | ||
|
|
||
| $this->itemExtensionMock | ||
| ->expects($this->once()) | ||
| ->method('getDiscounts') | ||
| ->willReturn([]); | ||
|
|
||
| $this->getDiscountsMock | ||
| ->expects($this->once()) | ||
| ->method('execute') | ||
| ->with($this->quoteMock, []); | ||
|
|
||
| $this->cartItemPrices->resolve($this->fieldMock, $this->contextMock, $this->resolveInfoMock, $this->valueMock); | ||
| } | ||
|
|
||
| public function testResolveWithoutModelInValueParameter(): void | ||
| { | ||
| $this->expectException(LocalizedException::class); | ||
| $this->expectExceptionMessage('"model" value should be specified'); | ||
| $this->cartItemPrices->resolve($this->fieldMock, $this->contextMock, $this->resolveInfoMock, $this->valueMock); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,9 +12,6 @@ | |
| use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface; | ||
| use Magento\Quote\Model\QuoteFactory; | ||
|
|
||
| /** | ||
| * Get masked quote id by reserved order id | ||
| */ | ||
| class GetMaskedQuoteIdByReservedOrderId | ||
| { | ||
| /** | ||
|
|
@@ -51,15 +48,21 @@ public function __construct( | |
| * Get masked quote id by reserved order id | ||
| * | ||
| * @param string $reservedOrderId | ||
| * @param bool $forceCollectTotal | ||
| * @return string | ||
| * @throws NoSuchEntityException | ||
| */ | ||
| public function execute(string $reservedOrderId): string | ||
| public function execute(string $reservedOrderId, bool $forceCollectTotal = false): string | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Parameter name |
||
| { | ||
| $quote = $this->quoteFactory->create(); | ||
| $quote->setSharedStoreIds(['*']); | ||
| $this->quoteResource->load($quote, $reservedOrderId, 'reserved_order_id'); | ||
|
|
||
| // If dataprovider is used, we need to collect totals manually and save quote | ||
| if ($forceCollectTotal) { | ||
| $this->quoteResource->save($quote->collectTotals()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess saving quote introduced in a method named "get" which will violates single responsibility.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Datafixture apply different tax while trigger this function from dev/tests/api-functional/testsuite/Magento/GraphQl/Weee/CartItemPricesWithFPTTest.php given the tax update totals should be saved. Given its a test I would suggest to keep this as-is unless you think differently. |
||
| } | ||
|
|
||
| return $this->quoteIdToMaskedId->execute((int)$quote->getId()); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Magic array of field names is hardcoded please define constant for these critical field names
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@engcom-Hotel define one const per field or total array as a single array const ?