Skip to content

Commit 7c7159e

Browse files
committed
Merge remote-tracking branch 'l3/MC-41030' into L3-PR-20210310
2 parents 872ba0d + 4b36743 commit 7c7159e

File tree

8 files changed

+834
-0
lines changed

8 files changed

+834
-0
lines changed

app/code/Magento/QuoteGraphQl/Model/Resolver/CartItemPrices.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
5858
$currencyCode = $cartItem->getQuote()->getQuoteCurrencyCode();
5959

6060
return [
61+
'model' => $cartItem,
6162
'price' => [
6263
'currency' => $currencyCode,
6364
'value' => $cartItem->getCalculationPrice(),
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\WeeeGraphQl\Model\Resolver\Quote;
9+
10+
use Magento\Framework\Exception\LocalizedException;
11+
use Magento\Framework\GraphQl\Config\Element\Field;
12+
use Magento\Framework\GraphQl\Query\ResolverInterface;
13+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
14+
use Magento\Store\Api\Data\StoreInterface;
15+
use Magento\Tax\Helper\Data as TaxHelper;
16+
use Magento\Tax\Model\Config;
17+
use Magento\Weee\Helper\Data;
18+
19+
/**
20+
* Resolver for FixedProductTax object that retrieves an array of FPT applied to a cart item
21+
*/
22+
class FixedProductTax implements ResolverInterface
23+
{
24+
/**
25+
* @var Data
26+
*/
27+
private $weeeHelper;
28+
29+
/**
30+
* @var TaxHelper
31+
*/
32+
private $taxHelper;
33+
34+
/**
35+
* @param Data $weeeHelper
36+
* @param TaxHelper $taxHelper
37+
*/
38+
public function __construct(Data $weeeHelper, TaxHelper $taxHelper)
39+
{
40+
$this->weeeHelper = $weeeHelper;
41+
$this->taxHelper = $taxHelper;
42+
}
43+
44+
/**
45+
* @inheritdoc
46+
*/
47+
public function resolve(
48+
Field $field,
49+
$context,
50+
ResolveInfo $info,
51+
array $value = null,
52+
array $args = null
53+
) {
54+
if (!isset($value['model'])) {
55+
throw new LocalizedException(__('"model" value should be specified'));
56+
}
57+
58+
$fptArray = [];
59+
$cartItem = $value['model'];
60+
61+
/** @var StoreInterface $store */
62+
$store = $context->getExtensionAttributes()->getStore();
63+
64+
if ($this->weeeHelper->isEnabled($store)) {
65+
$taxes = $this->weeeHelper->getApplied($cartItem);
66+
$displayInclTaxes = $this->taxHelper->getPriceDisplayType($store);
67+
foreach ($taxes as $tax) {
68+
$amount = $tax['amount'];
69+
if ($displayInclTaxes === Config::DISPLAY_TYPE_INCLUDING_TAX) {
70+
$amount = $tax['amount_incl_tax'];
71+
}
72+
$fptArray[] = [
73+
'amount' => [
74+
'value' => $amount,
75+
'currency' => $value['price']['currency'],
76+
],
77+
'label' => $tax['title']
78+
];
79+
}
80+
}
81+
82+
return $fptArray;
83+
}
84+
}
Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\WeeeGraphQl\Test\Unit\Model\Resolver;
9+
10+
use Magento\Framework\Exception\LocalizedException;
11+
use Magento\Framework\GraphQl\Config\Element\Field;
12+
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
13+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
14+
use Magento\GraphQl\Model\Query\ContextExtensionInterface;
15+
use Magento\Quote\Api\Data\CartItemInterface;
16+
use Magento\Store\Api\Data\StoreInterface;
17+
use Magento\Tax\Helper\Data as TaxHelper;
18+
use Magento\Weee\Helper\Data as WeeeHelper;
19+
use Magento\WeeeGraphQl\Model\Resolver\Quote\FixedProductTax;
20+
use PHPUnit\Framework\MockObject\MockObject;
21+
use PHPUnit\Framework\TestCase;
22+
23+
/**
24+
* Test FPT resolver for cart item
25+
*/
26+
class FixedProductTaxResolverTest extends TestCase
27+
{
28+
/**
29+
* @var MockObject|ContextInterface
30+
*/
31+
private $context;
32+
33+
/**
34+
* @var MockObject|WeeeHelper
35+
*/
36+
private $weeeHelper;
37+
38+
/**
39+
* @var TaxHelper|MockObject
40+
*/
41+
private $taxHelper;
42+
43+
/**
44+
* @var FixedProductTax
45+
*/
46+
private $resolver;
47+
48+
/**
49+
* @var array[]
50+
*/
51+
private $fpts = [
52+
[
53+
"title" => "FPT 2",
54+
"base_amount" => "0.5000",
55+
"amount" => 0.5,
56+
"row_amount" => 1.0,
57+
"base_row_amount" => 1.0,
58+
"base_amount_incl_tax" => "0.5500",
59+
"amount_incl_tax" => 0.55,
60+
"row_amount_incl_tax" => 1.1,
61+
"base_row_amount_incl_tax" => 1.1
62+
],
63+
[
64+
"title" => "FPT 1",
65+
"base_amount" => "1.0000",
66+
"amount" => 1,
67+
"row_amount" => 2,
68+
"base_row_amount" => 2,
69+
"base_amount_incl_tax" => "1.1000",
70+
"amount_incl_tax" => 1.1,
71+
"row_amount_incl_tax" => 2.2,
72+
"base_row_amount_incl_tax" => 2.2
73+
],
74+
[
75+
"title" => "FPT 2",
76+
"base_amount" => "1.5000",
77+
"amount" => 1.5,
78+
"row_amount" => 3.0,
79+
"base_row_amount" => 3.0,
80+
"base_amount_incl_tax" => "1.6500",
81+
"amount_incl_tax" => 1.65,
82+
"row_amount_incl_tax" => 3.30,
83+
"base_row_amount_incl_tax" => 3.30
84+
]
85+
];
86+
87+
/**
88+
* @inheritdoc
89+
*/
90+
protected function setUp(): void
91+
{
92+
$this->context = $this->getMockBuilder(ContextInterface::class)
93+
->setMethods(['getExtensionAttributes'])
94+
->getMockForAbstractClass();
95+
96+
$this->weeeHelper = $this->getMockBuilder(WeeeHelper::class)
97+
->disableOriginalConstructor()
98+
->onlyMethods(['isEnabled', 'getApplied'])
99+
->getMock();
100+
$this->taxHelper = $this->getMockBuilder(TaxHelper::class)
101+
->disableOriginalConstructor()
102+
->onlyMethods(['getPriceDisplayType'])
103+
->getMock();
104+
105+
$this->resolver = new FixedProductTax(
106+
$this->weeeHelper,
107+
$this->taxHelper,
108+
);
109+
}
110+
111+
/**
112+
* Verifies that exception is thrown if model is not specified
113+
*/
114+
public function testShouldThrowException(): void
115+
{
116+
$this->expectException(LocalizedException::class);
117+
$this->expectExceptionMessageMatches('/value should be specified/');
118+
119+
$this->resolver->resolve(
120+
$this->getFieldStub(),
121+
null,
122+
$this->getResolveInfoStub()
123+
);
124+
}
125+
126+
/**
127+
* Verifies that result is empty if FPT config is disabled
128+
*/
129+
public function testShouldReturnEmptyResult(): void
130+
{
131+
$store = $this->createMock(StoreInterface::class);
132+
$cartItem = $this->createMock(CartItemInterface::class);
133+
$contextExtensionAttributes = $this->createMock(ContextExtensionInterface::class);
134+
$contextExtensionAttributes->method('getStore')
135+
->willreturn($store);
136+
$this->context->method('getExtensionAttributes')
137+
->willReturn($contextExtensionAttributes);
138+
139+
$this->weeeHelper->method('isEnabled')
140+
->with($store)
141+
->willReturn(false);
142+
143+
$this->weeeHelper->expects($this->never())
144+
->method('getApplied');
145+
146+
$this->assertEquals(
147+
[],
148+
$this->resolver->resolve(
149+
$this->getFieldStub(),
150+
$this->context,
151+
$this->getResolveInfoStub(),
152+
['model' => $cartItem]
153+
)
154+
);
155+
}
156+
157+
/**
158+
* @dataProvider shouldReturnResultDataProvider
159+
* @param int $displayType
160+
* @param array $expected
161+
*/
162+
public function testShouldReturnResult(int $displayType, array $expected): void
163+
{
164+
$store = $this->createMock(StoreInterface::class);
165+
$cartItem = $this->createMock(CartItemInterface::class);
166+
$contextExtensionAttributes = $this->createMock(ContextExtensionInterface::class);
167+
$contextExtensionAttributes->method('getStore')
168+
->willreturn($store);
169+
$this->context->method('getExtensionAttributes')
170+
->willReturn($contextExtensionAttributes);
171+
172+
$this->weeeHelper->method('isEnabled')
173+
->with($store)
174+
->willReturn(true);
175+
176+
$this->weeeHelper->expects($this->once())
177+
->method('getApplied')
178+
->willReturn($this->fpts);
179+
180+
$this->taxHelper->expects($this->once())
181+
->method('getPriceDisplayType')
182+
->willReturn($displayType);
183+
184+
$this->assertEquals(
185+
$expected,
186+
$this->resolver->resolve(
187+
$this->getFieldStub(),
188+
$this->context,
189+
$this->getResolveInfoStub(),
190+
[
191+
'model' => $cartItem,
192+
'price' => [
193+
'currency' => 'USD'
194+
]
195+
]
196+
)
197+
);
198+
}
199+
200+
/**
201+
* @return array
202+
*/
203+
public function shouldReturnResultDataProvider(): array
204+
{
205+
return [
206+
[
207+
1,
208+
[
209+
[
210+
'label' => 'FPT 2',
211+
'amount' => [
212+
'value' => 0.5,
213+
'currency' => 'USD'
214+
]
215+
],
216+
[
217+
'label' => 'FPT 1',
218+
'amount' => [
219+
'value' => 1,
220+
'currency' => 'USD'
221+
]
222+
],
223+
[
224+
'label' => 'FPT 2',
225+
'amount' => [
226+
'value' => 1.5,
227+
'currency' => 'USD'
228+
]
229+
]
230+
]
231+
],
232+
[
233+
2,
234+
[
235+
[
236+
'label' => 'FPT 2',
237+
'amount' => [
238+
'value' => 0.55,
239+
'currency' => 'USD'
240+
]
241+
],
242+
[
243+
'label' => 'FPT 1',
244+
'amount' => [
245+
'value' => 1.1,
246+
'currency' => 'USD'
247+
]
248+
],
249+
[
250+
'label' => 'FPT 2',
251+
'amount' => [
252+
'value' => 1.65,
253+
'currency' => 'USD'
254+
]
255+
]
256+
]
257+
]
258+
];
259+
}
260+
261+
/**
262+
* @return MockObject|Field
263+
*/
264+
private function getFieldStub(): Field
265+
{
266+
/** @var MockObject|Field $fieldMock */
267+
$fieldMock = $this->getMockBuilder(Field::class)
268+
->disableOriginalConstructor()
269+
->getMock();
270+
return $fieldMock;
271+
}
272+
273+
/**
274+
* @return MockObject|ResolveInfo
275+
*/
276+
private function getResolveInfoStub(): ResolveInfo
277+
{
278+
/** @var MockObject|ResolveInfo $resolveInfoMock */
279+
$resolveInfoMock = $this->getMockBuilder(ResolveInfo::class)
280+
->disableOriginalConstructor()
281+
->getMock();
282+
return $resolveInfoMock;
283+
}
284+
}

app/code/Magento/WeeeGraphQl/etc/schema.graphqls

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ type ProductPrice {
1010
fixed_product_taxes: [FixedProductTax] @doc(description: "The multiple FPTs that can be applied to a product price.") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\FixedProductTax")
1111
}
1212

13+
type CartItemPrices {
14+
fixed_product_taxes: [FixedProductTax] @doc(description: "Applied FPT to the cart item.") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\Quote\\FixedProductTax")
15+
}
16+
1317
type FixedProductTax @doc(description: "A single FPT that can be applied to a product price.") {
1418
amount: Money @doc(description: "Amount of the FPT as a money object.")
1519
label: String @doc(description: "The label assigned to the FPT to be displayed on the frontend.")

0 commit comments

Comments
 (0)