Skip to content

Commit 936f07c

Browse files
ENGCOM-5181: [Checkout coverage] Added discount information to shopping cart #717
- Merge Pull Request magento/graphql-ce#717 from magento/graphql-ce:683-add-discount-information-cart - Merged commits: 1. 31b34ad 2. 8515566 3. fe708a2 4. 382d41f 5. a1e126c 6. 2d8bc6d
2 parents fdfaed6 + 2d8bc6d commit 936f07c

File tree

10 files changed

+339
-5
lines changed

10 files changed

+339
-5
lines changed

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
5656
'value' => $cartTotals->getSubtotalWithDiscount(), 'currency' => $currency
5757
],
5858
'applied_taxes' => $this->getAppliedTaxes($cartTotals, $currency),
59+
'discount' => $this->getDiscount($cartTotals, $currency),
5960
'model' => $quote
6061
];
6162
}
@@ -84,4 +85,22 @@ private function getAppliedTaxes(Total $total, string $currency): array
8485
}
8586
return $appliedTaxesData;
8687
}
88+
89+
/**
90+
* Returns information about an applied discount
91+
*
92+
* @param Total $total
93+
* @param string $currency
94+
* @return array|null
95+
*/
96+
private function getDiscount(Total $total, string $currency)
97+
{
98+
if ($total->getDiscountAmount() === 0) {
99+
return null;
100+
}
101+
return [
102+
'label' => explode(', ', $total->getDiscountDescription()),
103+
'amount' => ['value' => $total->getDiscountAmount(), 'currency' => $currency]
104+
];
105+
}
87106
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ type CartPrices {
146146
grand_total: Money
147147
subtotal_including_tax: Money
148148
subtotal_excluding_tax: Money
149+
discount: CartDiscount
149150
subtotal_with_discount_excluding_tax: Money
150151
applied_taxes: [CartTaxItem]
151152
}
@@ -155,6 +156,11 @@ type CartTaxItem {
155156
label: String!
156157
}
157158

159+
type CartDiscount {
160+
amount: Money!
161+
label: [String!]!
162+
}
163+
158164
type SetPaymentMethodOnCartOutput {
159165
cart: Cart!
160166
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
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\GraphQl\Quote\Customer;
9+
10+
use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId;
11+
use Magento\Integration\Api\CustomerTokenServiceInterface;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
use Magento\TestFramework\TestCase\GraphQlAbstract;
14+
15+
/**
16+
* Test is getting cart discount for registered customer.
17+
*/
18+
class CartDiscountTest extends GraphQlAbstract
19+
{
20+
/**
21+
* @var CustomerTokenServiceInterface
22+
*/
23+
private $customerTokenService;
24+
25+
/**
26+
* @var GetMaskedQuoteIdByReservedOrderId
27+
*/
28+
private $getMaskedQuoteIdByReservedOrderId;
29+
30+
protected function setUp()
31+
{
32+
$objectManager = Bootstrap::getObjectManager();
33+
$this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
34+
$this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class);
35+
}
36+
37+
/**
38+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
39+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/cart_rule_discount_no_coupon.php
40+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
41+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php
42+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
43+
*/
44+
public function testGetDiscountInformation()
45+
{
46+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
47+
$query = $this->getQuery($maskedQuoteId);
48+
$response = $this->graphQlQuery($query, [], '', $this->getHeaderMap());
49+
$discountResponse = $response['cart']['prices']['discount'];
50+
self::assertEquals(-10, $discountResponse['amount']['value']);
51+
self::assertEquals(['50% Off for all orders'], $discountResponse['label']);
52+
}
53+
54+
/**
55+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
56+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/cart_rule_discount_no_coupon.php
57+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
58+
* @magentoApiDataFixture Magento/Checkout/_files/discount_10percent_generalusers.php
59+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php
60+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
61+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/apply_coupon.php
62+
*/
63+
public function testGetDiscountInformationWithTwoRulesApplied()
64+
{
65+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
66+
$query = $this->getQuery($maskedQuoteId);
67+
$response = $this->graphQlQuery($query, [], '', $this->getHeaderMap());
68+
$discountResponse = $response['cart']['prices']['discount'];
69+
self::assertEquals(-11, $discountResponse['amount']['value']);
70+
self::assertEquals(['50% Off for all orders', 'Test Coupon for General'], $discountResponse['label']);
71+
}
72+
73+
/**
74+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
75+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
76+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php
77+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
78+
*/
79+
public function testGetDiscountInformationWithNoRulesApplied()
80+
{
81+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
82+
$query = $this->getQuery($maskedQuoteId);
83+
$response = $this->graphQlQuery($query, [], '', $this->getHeaderMap());
84+
self::assertEquals(null, $response['cart']['prices']['discount']);
85+
}
86+
87+
/**
88+
* Generates GraphQl query for retrieving cart discount
89+
*
90+
* @param string $maskedQuoteId
91+
* @return string
92+
*/
93+
private function getQuery(string $maskedQuoteId): string
94+
{
95+
return <<<QUERY
96+
{
97+
cart(cart_id: "$maskedQuoteId") {
98+
prices {
99+
discount {
100+
label
101+
amount {
102+
value
103+
currency
104+
}
105+
}
106+
}
107+
}
108+
}
109+
QUERY;
110+
}
111+
112+
/**
113+
* @param string $username
114+
* @param string $password
115+
* @return array
116+
*/
117+
private function getHeaderMap(string $username = 'customer@example.com', string $password = 'password'): array
118+
{
119+
$customerToken = $this->customerTokenService->createCustomerAccessToken($username, $password);
120+
$headerMap = ['Authorization' => 'Bearer ' . $customerToken];
121+
return $headerMap;
122+
}
123+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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\GraphQl\Quote\Guest;
9+
10+
use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId;
11+
use Magento\TestFramework\Helper\Bootstrap;
12+
use Magento\TestFramework\TestCase\GraphQlAbstract;
13+
14+
/**
15+
* Test is getting cart discount for guest customer.
16+
*/
17+
class CartDiscountTest extends GraphQlAbstract
18+
{
19+
/**
20+
* @var GetMaskedQuoteIdByReservedOrderId
21+
*/
22+
private $getMaskedQuoteIdByReservedOrderId;
23+
24+
protected function setUp()
25+
{
26+
$objectManager = Bootstrap::getObjectManager();
27+
$this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
28+
}
29+
30+
/**
31+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/cart_rule_discount_no_coupon.php
32+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
33+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
34+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
35+
*/
36+
public function testGetDiscountInformation()
37+
{
38+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
39+
$query = $this->getQuery($maskedQuoteId);
40+
$response = $this->graphQlQuery($query);
41+
$discountResponse = $response['cart']['prices']['discount'];
42+
self::assertEquals(-10, $discountResponse['amount']['value']);
43+
self::assertEquals(['50% Off for all orders'], $discountResponse['label']);
44+
}
45+
46+
/**
47+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/cart_rule_discount_no_coupon.php
48+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
49+
* @magentoApiDataFixture Magento/SalesRule/_files/coupon_code_with_wildcard.php
50+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
51+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
52+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/apply_coupon.php
53+
*/
54+
public function testGetDiscountInformationWithTwoRulesApplied()
55+
{
56+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
57+
$query = $this->getQuery($maskedQuoteId);
58+
$response = $this->graphQlQuery($query);
59+
$discountResponse = $response['cart']['prices']['discount'];
60+
self::assertEquals(-15, $discountResponse['amount']['value']);
61+
self::assertEquals(['50% Off for all orders', '5$ fixed discount on whole cart'], $discountResponse['label']);
62+
}
63+
64+
/**
65+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
66+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
67+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
68+
*/
69+
public function testGetDiscountInformationWithNoRulesApplied()
70+
{
71+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
72+
$query = $this->getQuery($maskedQuoteId);
73+
$response = $this->graphQlQuery($query);
74+
self::assertEquals(null, $response['cart']['prices']['discount']);
75+
}
76+
77+
/**
78+
* Generates GraphQl query for retrieving cart discount.
79+
*
80+
* @param string $maskedQuoteId
81+
* @return string
82+
*/
83+
private function getQuery(string $maskedQuoteId): string
84+
{
85+
return <<<QUERY
86+
{
87+
cart(cart_id: "$maskedQuoteId") {
88+
prices {
89+
discount {
90+
label
91+
amount {
92+
value
93+
currency
94+
}
95+
}
96+
}
97+
}
98+
}
99+
QUERY;
100+
}
101+
}

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/CartTotalsTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ public function testGetTotalsWithNoTaxApplied()
8787
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
8888
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
8989
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
90-
* @group recent
9190
*/
9291
public function testGetCartTotalsWithNoAddressSet()
9392
{

dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_generalusers.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
$data = [
1515
'name' => 'Test Coupon for General',
1616
'is_active' => true,
17+
'store_labels' => [0 => 'Test Coupon for General'],
1718
'website_ids' => [
1819
\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
1920
\Magento\Store\Model\StoreManagerInterface::class
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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+
use Magento\Customer\Model\GroupManagement as CustomerGroupManagement;
9+
use Magento\Framework\Api\DataObjectHelper;
10+
use Magento\SalesRule\Api\Data\RuleInterface;
11+
use Magento\SalesRule\Api\Data\RuleLabelInterface;
12+
use Magento\SalesRule\Api\RuleRepositoryInterface;
13+
use Magento\SalesRule\Model\Data\Rule as RuleData;
14+
use Magento\SalesRule\Model\Data\RuleLabelFactory;
15+
use Magento\Store\Model\StoreManagerInterface;
16+
use Magento\TestFramework\Helper\Bootstrap;
17+
18+
$objectManager = Bootstrap::getObjectManager();
19+
/** @var RuleRepositoryInterface $ruleRepository */
20+
$ruleRepository = $objectManager->get(RuleRepositoryInterface::class);
21+
/** @var DataObjectHelper $dataObjectHelper */
22+
$dataObjectHelper = Bootstrap::getObjectManager()->get(DataObjectHelper::class);
23+
$ruleLabel = $objectManager->create(RuleLabelInterface::class);
24+
$ruleLabelFactory = $objectManager->get(RuleLabelFactory::class);
25+
26+
27+
/** @var RuleData $salesRule */
28+
$salesRule = $objectManager->create(RuleData::class);
29+
/** @var RuleLabelInterface $ruleLabel */
30+
$ruleLabel = $ruleLabelFactory->create();
31+
$ruleLabel->setStoreId(0);
32+
$ruleLabel->setStoreLabel('50% Off for all orders');
33+
$ruleData = [
34+
'name' => '50% Off for all orders',
35+
'is_active' => 1,
36+
'customer_group_ids' => [CustomerGroupManagement::NOT_LOGGED_IN_ID, 1],
37+
'coupon_type' => RuleData::COUPON_TYPE_NO_COUPON,
38+
'conditions' => [],
39+
'simple_action' => 'by_percent',
40+
'discount_amount' => 50,
41+
'discount_step' => 0,
42+
'website_ids' => [
43+
$objectManager->get(
44+
StoreManagerInterface::class
45+
)->getWebsite()->getId(),
46+
],
47+
'discount_qty' => 0,
48+
'apply_to_shipping' => 1,
49+
'simple_free_shipping' => 1,
50+
'stop_rules_processing' => 0
51+
];
52+
$dataObjectHelper->populateWithArray($salesRule, $ruleData, RuleInterface::class);
53+
$salesRule->setStoreLabels([$ruleLabel]);
54+
55+
$ruleRepository->save($salesRule);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
use Magento\SalesRule\Api\RuleRepositoryInterface;
9+
use Magento\SalesRule\Model\ResourceModel\Rule\CollectionFactory as RuleCollectionFactory;
10+
use Magento\TestFramework\Helper\Bootstrap;
11+
12+
$objectManager = Bootstrap::getObjectManager();
13+
/** @var RuleRepositoryInterface $ruleRepository */
14+
$ruleRepository = $objectManager->get(RuleRepositoryInterface::class);
15+
/** @var RuleCollectionFactory $ruleCollectionFactory */
16+
$ruleCollectionFactory = $objectManager->get(RuleCollectionFactory::class);
17+
$ruleCollection = $ruleCollectionFactory->create();
18+
19+
foreach ($ruleCollection->getItems() as $rule) {
20+
$ruleRepository->deleteById($rule->getRuleId());
21+
}

dev/tests/integration/testsuite/Magento/SalesRule/_files/cart_rule_100_percent_off_rollback.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,19 @@
55
*/
66
declare(strict_types=1);
77

8+
use Magento\Framework\Registry;
9+
use Magento\SalesRule\Api\RuleRepositoryInterface;
10+
use Magento\TestFramework\Helper\Bootstrap;
11+
12+
$objectManager = Bootstrap::getObjectManager();
813
/** @var Magento\Framework\Registry $registry */
9-
$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
14+
$registry = Bootstrap::getObjectManager()->get(Registry::class);
15+
/** @var RuleRepositoryInterface $ruleRepository */
16+
$ruleRepository = $objectManager->get(RuleRepositoryInterface::class);
1017

1118
/** @var Magento\SalesRule\Model\Rule $rule */
12-
$rule = $registry->registry('cart_rule_100_percent_off');
13-
if ($rule) {
14-
$rule->delete();
19+
$ruleId = $registry->registry('Magento/SalesRule/_files/cart_rule_100_percent_off');
20+
21+
if ($ruleId) {
22+
$ruleRepository->deleteById($ruleId);
1523
}

0 commit comments

Comments
 (0)