Skip to content

Commit edfbc39

Browse files
authored
Merge pull request #6191 from magento-honey-badgers/honey-pr-bundle
[honey] MC-37582: Fix Failing WebAPI GraphQL tests when DB table prefixes are enabled
2 parents 8d54bed + a87d55b commit edfbc39

File tree

13 files changed

+293
-171
lines changed

13 files changed

+293
-171
lines changed

app/code/Magento/CatalogGraphQl/DataProvider/Product/LayeredNavigation/AttributeOptionProvider.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ public function getOptions(array $optionIds, ?int $storeId, array $attributeCode
6464
'attribute_label' => 'a.frontend_label',
6565
]
6666
)
67+
->joinLeft(
68+
['attribute_label' => $this->resourceConnection->getTableName('eav_attribute_label')],
69+
"a.attribute_id = attribute_label.attribute_id AND attribute_label.store_id = {$storeId}",
70+
[
71+
'attribute_store_label' => 'attribute_label.value',
72+
]
73+
)
6774
->joinLeft(
6875
['options' => $this->resourceConnection->getTableName('eav_attribute_option')],
6976
'a.attribute_id = options.attribute_id',
@@ -119,7 +126,8 @@ private function formatResult(\Magento\Framework\DB\Select $select): array
119126
$result[$option['attribute_code']] = [
120127
'attribute_id' => $option['attribute_id'],
121128
'attribute_code' => $option['attribute_code'],
122-
'attribute_label' => $option['attribute_label'],
129+
'attribute_label' => $option['attribute_store_label']
130+
? $option['attribute_store_label'] : $option['attribute_label'],
123131
'options' => [],
124132
];
125133
}

app/code/Magento/Wishlist/Model/Wishlist/RemoveProductsFromWishlist.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\Wishlist\Model\Wishlist;
99

10+
use Magento\Framework\Exception\LocalizedException;
1011
use Magento\Wishlist\Model\Item as WishlistItem;
1112
use Magento\Wishlist\Model\ItemFactory as WishlistItemFactory;
1213
use Magento\Wishlist\Model\ResourceModel\Item as WishlistItemResource;
@@ -63,7 +64,7 @@ public function __construct(
6364
public function execute(Wishlist $wishlist, array $wishlistItemsIds): WishlistOutput
6465
{
6566
foreach ($wishlistItemsIds as $wishlistItemId) {
66-
$this->removeItemFromWishlist((int) $wishlistItemId);
67+
$this->removeItemFromWishlist((int) $wishlistItemId, $wishlist);
6768
}
6869

6970
return $this->prepareOutput($wishlist);
@@ -73,12 +74,22 @@ public function execute(Wishlist $wishlist, array $wishlistItemsIds): WishlistOu
7374
* Remove product item from wishlist
7475
*
7576
* @param int $wishlistItemId
77+
* @param Wishlist $wishlist
7678
*
7779
* @return void
7880
*/
79-
private function removeItemFromWishlist(int $wishlistItemId): void
81+
private function removeItemFromWishlist(int $wishlistItemId, Wishlist $wishlist): void
8082
{
8183
try {
84+
if ($wishlist->getItem($wishlistItemId) == null) {
85+
throw new LocalizedException(
86+
__(
87+
'The wishlist item with ID "%id" does not belong to the wishlist',
88+
['id' => $wishlistItemId]
89+
)
90+
);
91+
}
92+
$wishlist->getItemCollection()->clear();
8293
/** @var WishlistItem $wishlistItem */
8394
$wishlistItem = $this->wishlistItemFactory->create();
8495
$this->wishlistItemResource->load($wishlistItem, $wishlistItemId);
@@ -90,6 +101,8 @@ private function removeItemFromWishlist(int $wishlistItemId): void
90101
}
91102

92103
$this->wishlistItemResource->delete($wishlistItem);
104+
} catch (LocalizedException $exception) {
105+
$this->addError($exception->getMessage());
93106
} catch (\Exception $e) {
94107
$this->addError(
95108
__(

app/code/Magento/Wishlist/Model/Wishlist/UpdateProductsInWishlist.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ public function execute(Wishlist $wishlist, array $wishlistItems): WishlistOutpu
9090
private function updateItemInWishlist(Wishlist $wishlist, WishlistItemData $wishlistItemData): void
9191
{
9292
try {
93+
if ($wishlist->getItem($wishlistItemData->getId()) == null) {
94+
throw new LocalizedException(
95+
__(
96+
'The wishlist item with ID "%id" does not belong to the wishlist',
97+
['id' => $wishlistItemData->getId()]
98+
)
99+
);
100+
}
101+
$wishlist->getItemCollection()->clear();
93102
$options = $this->buyRequestBuilder->build($wishlistItemData);
94103
/** @var WishlistItem $wishlistItem */
95104
$wishlistItem = $this->wishlistItemFactory->create();

dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoriesQuery/CategoryTreeTest.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
use Magento\Catalog\Api\ProductRepositoryInterface;
1212
use Magento\Catalog\Model\CategoryRepository;
1313
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
14+
use Magento\Framework\App\ResourceConnection;
1415
use Magento\Framework\EntityManager\MetadataPool;
1516
use Magento\Store\Model\Store;
1617
use Magento\Store\Model\StoreManagerInterface;
18+
use Magento\TestFramework\Helper\Bootstrap;
1719
use Magento\TestFramework\ObjectManager;
1820
use Magento\TestFramework\TestCase\GraphQlAbstract;
1921

@@ -564,10 +566,12 @@ public function testCategoryImage(?string $imagePrefix)
564566
->addAttributeToFilter('name', ['eq' => 'Parent Image Category'])
565567
->getFirstItem();
566568
$categoryId = $categoryModel->getId();
569+
/** @var ResourceConnection $resourceConnection */
570+
$resourceConnection = Bootstrap::getObjectManager()->create(ResourceConnection::class);
571+
$connection = $resourceConnection->getConnection();
567572

568573
if ($imagePrefix !== null) {
569574
// update image to account for different stored image formats
570-
$connection = $categoryCollection->getConnection();
571575
$productLinkField = $this->metadataPool
572576
->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class)
573577
->getLinkField();
@@ -577,20 +581,20 @@ public function testCategoryImage(?string $imagePrefix)
577581
$imageAttributeValue = $imagePrefix . basename($categoryModel->getImage());
578582

579583
if (!empty($imageAttributeValue)) {
580-
$query = sprintf(
584+
$sqlQuery = sprintf(
581585
'UPDATE %s SET `value` = "%s" ' .
582586
'WHERE `%s` = %d ' .
583587
'AND `store_id`= %d ' .
584588
'AND `attribute_id` = ' .
585589
'(SELECT `ea`.`attribute_id` FROM %s ea WHERE `ea`.`attribute_code` = "image" LIMIT 1)',
586-
$connection->getTableName('catalog_category_entity_varchar'),
590+
$resourceConnection->getTableName('catalog_category_entity_varchar'),
587591
$imageAttributeValue,
588592
$productLinkField,
589593
$categoryModel->getData($productLinkField),
590594
$defaultStoreId,
591-
$connection->getTableName('eav_attribute')
595+
$resourceConnection->getTableName('eav_attribute')
592596
);
593-
$connection->query($query);
597+
$connection->query($sqlQuery);
594598
}
595599
}
596600

dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,20 @@
1212
use Magento\Catalog\Api\ProductRepositoryInterface;
1313
use Magento\Catalog\Model\CategoryRepository;
1414
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
15+
use Magento\Framework\App\ResourceConnection;
1516
use Magento\Framework\DataObject;
1617
use Magento\Framework\EntityManager\MetadataPool;
1718
use Magento\Store\Model\Store;
1819
use Magento\Store\Model\StoreManagerInterface;
20+
use Magento\TestFramework\Helper\Bootstrap;
1921
use Magento\TestFramework\ObjectManager;
2022
use Magento\TestFramework\TestCase\GraphQl\ResponseContainsErrorsException;
2123
use Magento\TestFramework\TestCase\GraphQlAbstract;
2224

2325
/**
2426
* Test loading of category tree
27+
*
28+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2529
*/
2630
class CategoryTest extends GraphQlAbstract
2731
{
@@ -47,7 +51,7 @@ class CategoryTest extends GraphQlAbstract
4751

4852
protected function setUp(): void
4953
{
50-
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
54+
$this->objectManager = Bootstrap::getObjectManager();
5155
$this->categoryRepository = $this->objectManager->get(CategoryRepository::class);
5256
$this->store = $this->objectManager->get(Store::class);
5357
$this->metadataPool = $this->objectManager->get(MetadataPool::class);
@@ -587,9 +591,12 @@ public function testCategoryImage(?string $imagePrefix)
587591
->getFirstItem();
588592
$categoryId = $categoryModel->getId();
589593

594+
/** @var ResourceConnection $resourceConnection */
595+
$resourceConnection = Bootstrap::getObjectManager()->create(ResourceConnection::class);
596+
$connection = $resourceConnection->getConnection();
597+
590598
if ($imagePrefix !== null) {
591-
// update image to account for different stored image formats
592-
$connection = $categoryCollection->getConnection();
599+
// update image to account for different stored image format
593600
$productLinkField = $this->metadataPool
594601
->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class)
595602
->getLinkField();
@@ -599,20 +606,20 @@ public function testCategoryImage(?string $imagePrefix)
599606
$imageAttributeValue = $imagePrefix . basename($categoryModel->getImage());
600607

601608
if (!empty($imageAttributeValue)) {
602-
$query = sprintf(
609+
$sqlQuery = sprintf(
603610
'UPDATE %s SET `value` = "%s" ' .
604611
'WHERE `%s` = %d ' .
605612
'AND `store_id`= %d ' .
606613
'AND `attribute_id` = ' .
607614
'(SELECT `ea`.`attribute_id` FROM %s ea WHERE `ea`.`attribute_code` = "image" LIMIT 1)',
608-
$connection->getTableName('catalog_category_entity_varchar'),
615+
$resourceConnection->getTableName('catalog_category_entity_varchar'),
609616
$imageAttributeValue,
610617
$productLinkField,
611618
$categoryModel->getData($productLinkField),
612619
$defaultStoreId,
613-
$connection->getTableName('eav_attribute')
620+
$resourceConnection->getTableName('eav_attribute')
614621
);
615-
$connection->query($query);
622+
$connection->query($sqlQuery);
616623
}
617624
}
618625

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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\Catalog;
9+
10+
use Exception;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\TestFramework\TestCase\GraphQlAbstract;
13+
14+
class ProductAttributeStoreTest extends GraphQlAbstract
15+
{
16+
/**
17+
* Test that custom attribute labels are returned respecting store
18+
*
19+
* @magentoApiDataFixture Magento/Store/_files/store.php
20+
* @magentoApiDataFixture Magento/Catalog/_files/products_with_layered_navigation_attribute_store_options.php
21+
* @throws LocalizedException
22+
*/
23+
public function testAttributeStoreLabels(): void
24+
{
25+
$this->attributeLabelTest('Test Configurable Default Store');
26+
$this->attributeLabelTest('Test Configurable Test Store', ['Store' => 'test']);
27+
}
28+
29+
/**
30+
* @param $expectedLabel
31+
* @param array $headers
32+
* @throws LocalizedException
33+
* @throws Exception
34+
*/
35+
private function attributeLabelTest($expectedLabel, array $headers = []): void
36+
{
37+
$query = <<<QUERY
38+
{
39+
products(search:"Simple",
40+
pageSize: 3
41+
currentPage: 1
42+
)
43+
{
44+
aggregations
45+
{
46+
attribute_code
47+
label
48+
}
49+
}
50+
}
51+
QUERY;
52+
$response = $this->graphQlQuery($query, [], '', $headers);
53+
$this->assertNotEmpty($response['products']['aggregations']);
54+
$attributes = $response['products']['aggregations'];
55+
foreach ($attributes as $attribute) {
56+
if ($attribute['attribute_code'] === 'test_configurable') {
57+
$this->assertEquals($expectedLabel, $attribute['label']);
58+
}
59+
}
60+
}
61+
}

dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/DeleteProductsFromWishlistTest.php

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,34 @@ public function testDeleteWishlistItemFromWishlist(): void
5555
$this->assertEmpty($wishlistResponse['items_v2']);
5656
}
5757

58+
/**
59+
* Test deleting the wishlist item of another customer
60+
*
61+
* @magentoConfigFixture default_store wishlist/general/active 1
62+
* @magentoApiDataFixture Magento/Wishlist/_files/two_wishlists_for_two_diff_customers.php
63+
*/
64+
public function testUnauthorizedWishlistItemDelete()
65+
{
66+
$wishlist = $this->getWishlist();
67+
$wishlistItem = $wishlist['customer']['wishlist']['items_v2'][0];
68+
$wishlist2 = $this->getWishlist('[email protected]');
69+
$wishlist2Id = $wishlist2['customer']['wishlist']['id'];
70+
$query = $this->getQuery((int) $wishlist2Id, (int) $wishlistItem['id']);
71+
$response = $this->graphQlMutation(
72+
$query,
73+
[],
74+
'',
75+
$this->getHeaderMap('[email protected]')
76+
);
77+
self::assertEquals(1, $response['removeProductsFromWishlist']['wishlist']['items_count']);
78+
self::assertNotEmpty($response['removeProductsFromWishlist']['wishlist']['items_v2'], 'empty wish list items');
79+
self::assertCount(1, $response['removeProductsFromWishlist']['wishlist']['items_v2']);
80+
self::assertEquals(
81+
'The wishlist item with ID "'.$wishlistItem['id'].'" does not belong to the wishlist',
82+
$response['removeProductsFromWishlist']['user_errors'][0]['message']
83+
);
84+
}
85+
5886
/**
5987
* Authentication header map
6088
*
@@ -116,9 +144,9 @@ private function getQuery(
116144
*
117145
* @throws Exception
118146
*/
119-
public function getWishlist(): array
147+
public function getWishlist(string $username = '[email protected]'): array
120148
{
121-
return $this->graphQlQuery($this->getCustomerWishlistQuery(), [], '', $this->getHeaderMap());
149+
return $this->graphQlQuery($this->getCustomerWishlistQuery(), [], '', $this->getHeaderMap($username));
122150
}
123151

124152
/**

dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/UpdateProductsFromWishlistTest.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,37 @@ public function testUpdateSimpleProductFromWishlist(): void
5757
$this->assertEquals($description, $wishlistResponse['items_v2'][0]['description']);
5858
}
5959

60+
/**
61+
* Test updating the wishlist item of another customer
62+
*
63+
* @magentoConfigFixture default_store wishlist/general/active 1
64+
* @magentoApiDataFixture Magento/Customer/_files/two_customers.php
65+
* @magentoApiDataFixture Magento/Wishlist/_files/two_wishlists_for_two_diff_customers.php
66+
*/
67+
public function testUnauthorizedWishlistItemUpdate()
68+
{
69+
$wishlist = $this->getWishlist();
70+
$wishlistItem = $wishlist['customer']['wishlist']['items_v2'][0];
71+
$wishlist2 = $this->getWishlist('[email protected]');
72+
$wishlist2Id = $wishlist2['customer']['wishlist']['id'];
73+
$qty = 2;
74+
$description = 'New Description';
75+
$updateWishlistQuery = $this->getQuery((int) $wishlist2Id, (int) $wishlistItem['id'], $qty, $description);
76+
$response = $this->graphQlMutation(
77+
$updateWishlistQuery,
78+
[],
79+
'',
80+
$this->getHeaderMap('[email protected]')
81+
);
82+
self::assertEquals(1, $response['updateProductsInWishlist']['wishlist']['items_count']);
83+
self::assertNotEmpty($response['updateProductsInWishlist']['wishlist']['items_v2'], 'empty wish list items');
84+
self::assertCount(1, $response['updateProductsInWishlist']['wishlist']['items_v2']);
85+
self::assertEquals(
86+
'The wishlist item with ID "'.$wishlistItem['id'].'" does not belong to the wishlist',
87+
$response['updateProductsInWishlist']['user_errors'][0]['message']
88+
);
89+
}
90+
6091
/**
6192
* Authentication header map
6293
*
@@ -124,13 +155,14 @@ private function getQuery(
124155
/**
125156
* Get wishlist result
126157
*
158+
* @param string $username
127159
* @return array
128160
*
129161
* @throws Exception
130162
*/
131-
public function getWishlist(): array
163+
public function getWishlist(string $username = '[email protected]'): array
132164
{
133-
return $this->graphQlQuery($this->getCustomerWishlistQuery(), [], '', $this->getHeaderMap());
165+
return $this->graphQlQuery($this->getCustomerWishlistQuery(), [], '', $this->getHeaderMap($username));
134166
}
135167

136168
/**

dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_layered_navigation_attribute_store_options.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@
5050
'is_visible_on_front' => 1,
5151
'used_in_product_listing' => 1,
5252
'used_for_sort_by' => 1,
53-
'frontend_label' => ['Test Configurable'],
53+
'frontend_label' => [
54+
Store::DEFAULT_STORE_ID => 'Test Configurable Admin Store',
55+
Store::DISTRO_STORE_ID => 'Test Configurable Default Store',
56+
$store->getId() => 'Test Configurable Test Store'
57+
],
5458
'backend_type' => 'int',
5559
'option' => [
5660
'value' => ['option_0' => [

0 commit comments

Comments
 (0)