Skip to content

Commit b455722

Browse files
Merge branch 'ACQE-8879' into ACQE-functional-deployment-version18
2 parents 2433855 + 738c562 commit b455722

File tree

1 file changed

+211
-0
lines changed

1 file changed

+211
-0
lines changed
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GraphQl\Wishlist;
9+
10+
use Magento\Catalog\Api\Data\ProductCustomOptionInterface;
11+
use Magento\Catalog\Api\ProductCustomOptionRepositoryInterface;
12+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
13+
use Magento\Customer\Test\Fixture\Customer as CustomerFixture;
14+
use Magento\Framework\ObjectManagerInterface;
15+
use Magento\Framework\Exception\AuthenticationException;
16+
use Magento\Framework\Exception\EmailNotConfirmedException;
17+
use Magento\Integration\Api\CustomerTokenServiceInterface;
18+
use Magento\TestFramework\Fixture\Config;
19+
use Magento\TestFramework\Fixture\DataFixture;
20+
use Magento\TestFramework\Fixture\DataFixtureStorage;
21+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
22+
use Magento\TestFramework\Helper\Bootstrap;
23+
use Magento\TestFramework\TestCase\GraphQlAbstract;
24+
25+
/**
26+
* Test to verify add simple product with required field and area options to wishlist via GraphQL
27+
*/
28+
class SimpleProductWithCustomOptionToWishlistTest extends GraphQlAbstract
29+
{
30+
/**
31+
* @var CustomerTokenServiceInterface
32+
*/
33+
private CustomerTokenServiceInterface $customerTokenService;
34+
35+
/**
36+
* @var ProductCustomOptionRepositoryInterface
37+
*/
38+
private ProductCustomOptionRepositoryInterface $productCustomOptionRepository;
39+
40+
/**
41+
* @var ObjectManagerInterface
42+
*/
43+
private ObjectManagerInterface $objectManager;
44+
45+
/**
46+
* @var DataFixtureStorage
47+
*/
48+
private DataFixtureStorage $fixtures;
49+
50+
/**
51+
* @return void
52+
*/
53+
protected function setUp(): void
54+
{
55+
parent::setUp();
56+
$this->objectManager = Bootstrap::getObjectManager();
57+
$this->fixtures = $this->objectManager->get(DataFixtureStorageManager::class)->getStorage();
58+
$this->customerTokenService = $this->objectManager->get(CustomerTokenServiceInterface::class);
59+
$this->productCustomOptionRepository = $this->objectManager->get(ProductCustomOptionRepositoryInterface::class);
60+
}
61+
62+
#[
63+
Config('wishlist/general/active', '1', 'store', 'default'),
64+
DataFixture(
65+
ProductFixture::class,
66+
[
67+
'sku' => 'simple_co',
68+
'name' => 'Simple CO',
69+
'price' => 10,
70+
'options' => [
71+
[
72+
'type' => ProductCustomOptionInterface::OPTION_TYPE_FIELD,
73+
'title' => 'field_opt',
74+
'is_require' => true,
75+
],
76+
[
77+
'type' => ProductCustomOptionInterface::OPTION_TYPE_AREA,
78+
'title' => 'area_opt',
79+
'is_require' => true,
80+
],
81+
],
82+
],
83+
as: 'product1'
84+
),
85+
DataFixture(CustomerFixture::class, as: 'customer'),
86+
]
87+
/**
88+
* Test to verify adding simple product with custom option to wishlist
89+
*
90+
* @return void
91+
*/
92+
public function testAddSimpleProductWithCustomOptionsToWishlist(): void
93+
{
94+
$sku = 'simple_co';
95+
$uids = $this->getEnteredOptionUids($sku, [
96+
ProductCustomOptionInterface::OPTION_TYPE_FIELD,
97+
ProductCustomOptionInterface::OPTION_TYPE_AREA,
98+
]);
99+
$query = $this->getMutation($sku, $uids['field'], $uids['area']);
100+
$response = $this->graphQlMutation($query, [], '', $this->getHeadersMap());
101+
$this->assertArrayHasKey('addProductsToWishlist', $response);
102+
$this->assertArrayHasKey('wishlist', $response['addProductsToWishlist']);
103+
$this->assertEmpty($response['addProductsToWishlist']['user_errors'] ?? []);
104+
$wishlist = $response['addProductsToWishlist']['wishlist'];
105+
$this->assertEquals(1, $wishlist['items_count']);
106+
$this->assertCount(1, $wishlist['items_v2']['items']);
107+
$item = $wishlist['items_v2']['items'][0];
108+
$this->assertEquals($sku, $item['product']['sku']);
109+
$this->assertCount(2, $item['customizable_options']);
110+
foreach ($item['customizable_options'] as $opt) {
111+
if ($opt['type'] === 'field') {
112+
$this->assertEquals('test field value', $opt['values'][0]['value']);
113+
}
114+
if ($opt['type'] === 'area') {
115+
$this->assertEquals('test area value', $opt['values'][0]['value']);
116+
}
117+
}
118+
}
119+
120+
/**
121+
* Get addProductsToWishlist mutation
122+
*
123+
* @param string $sku
124+
* @param string $fieldUid
125+
* @param string $areaUid
126+
* @param int $wishlistId
127+
* @return string
128+
*/
129+
private function getMutation(string $sku, string $fieldUid, string $areaUid, int $wishlistId = 0): string
130+
{
131+
return <<<MUTATION
132+
mutation {
133+
addProductsToWishlist(
134+
wishlistId: {$wishlistId},
135+
wishlistItems: [
136+
{
137+
sku: "{$sku}"
138+
quantity: 1
139+
entered_options: [
140+
{ uid: "{$fieldUid}", value: "test field value" }
141+
{ uid: "{$areaUid}", value: "test area value" }
142+
]
143+
}
144+
]
145+
) {
146+
user_errors { code message }
147+
wishlist {
148+
id
149+
items_count
150+
items_v2(currentPage:1,pageSize:10) {
151+
items {
152+
id
153+
quantity
154+
customizable_options {
155+
customizable_option_uid
156+
label
157+
type
158+
values { label value }
159+
}
160+
product { sku }
161+
}
162+
}
163+
}
164+
}
165+
}
166+
MUTATION;
167+
}
168+
169+
/**
170+
* Get product custom option uids
171+
*
172+
* @param string $sku
173+
* @param array $types
174+
* @return array
175+
*/
176+
private function getEnteredOptionUids(string $sku, array $types): array
177+
{
178+
$customOptions = $this->productCustomOptionRepository->getList($sku);
179+
$map = [];
180+
foreach ($customOptions as $customOption) {
181+
$type = $customOption->getType();
182+
if (!in_array($type, $types, true)) {
183+
continue;
184+
}
185+
if (!isset($map[$type])) {
186+
$map[$type] = base64_encode('custom-option/' . (int) $customOption->getOptionId());
187+
}
188+
if (count($map) === count($types)) {
189+
break;
190+
}
191+
}
192+
return [
193+
'field' => $map[ProductCustomOptionInterface::OPTION_TYPE_FIELD],
194+
'area' => $map[ProductCustomOptionInterface::OPTION_TYPE_AREA],
195+
];
196+
}
197+
198+
/**
199+
* Get customer token for authentication
200+
*
201+
* @return string[]
202+
* @throws AuthenticationException
203+
* @throws EmailNotConfirmedException
204+
*/
205+
private function getHeadersMap(): array
206+
{
207+
$username = $this->fixtures->get('customer')->getEmail();
208+
$customerToken = $this->customerTokenService->createCustomerAccessToken($username, 'password');
209+
return ['Authorization' => 'Bearer ' . $customerToken];
210+
}
211+
}

0 commit comments

Comments
 (0)