mirror of
https://github.com/bdnugget/magento2.git
synced 2026-11-07 09:17:35 +00:00
Merge branch '2.4-develop' of https://github.com/magento-commerce/magento2ce into ACP2E-2300
# Conflicts: # dev/tests/integration/testsuite/Magento/GraphQl/_files/state-skip-list.php
This commit is contained in:
1 parent
5ec7414844
commit
654f273e78
66 files changed
+4127
-1406
No files matched your search
+4
-1
@@ -114,11 +114,13 @@
|
||||
"magento/module-admin-analytics": "*",
|
||||
"magento/module-admin-notification": "*",
|
||||
"magento/module-advanced-pricing-import-export": "*",
|
||||
"magento/module-advanced-search": "*",
|
||||
"magento/module-amqp": "*",
|
||||
"magento/module-analytics": "*",
|
||||
"magento/module-application-performance-monitor": "*",
|
||||
"magento/module-application-performance-monitor-new-relic": "*",
|
||||
"magento/module-asynchronous-operations": "*",
|
||||
"magento/module-authorization": "*",
|
||||
"magento/module-advanced-search": "*",
|
||||
"magento/module-backend": "*",
|
||||
"magento/module-backup": "*",
|
||||
"magento/module-bundle": "*",
|
||||
@@ -182,6 +184,7 @@
|
||||
"magento/module-google-gtag": "*",
|
||||
"magento/module-graph-ql": "*",
|
||||
"magento/module-graph-ql-cache": "*",
|
||||
"magento/module-graph-ql-new-relic": "*",
|
||||
"magento/module-graph-ql-resolver-cache": "*",
|
||||
"magento/module-catalog-graph-ql": "*",
|
||||
"magento/module-catalog-cms-graph-ql": "*",
|
||||
|
||||
+1
-4
@@ -1,10 +1,7 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
*
|
||||
* ADOBE CONFIDENTIAL
|
||||
* ___________________
|
||||
*
|
||||
* Copyright 2014 Adobe
|
||||
* Copyright 2023 Adobe
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* NOTICE: All information contained herein is, and remains
|
||||
|
||||
+10
-19
@@ -188,26 +188,17 @@ class ProductRepositoryMultiWebsiteTest extends WebapiAbstract
|
||||
/** @var ScopeOverriddenValue $scopeOverriddenValue */
|
||||
$scopeOverriddenValue = $this->objectManager->get(ScopeOverriddenValue::class);
|
||||
$storeId = $store->load('fixture_third_store', 'code')->getId();
|
||||
$this->assertFalse($scopeOverriddenValue->containsValue(
|
||||
ProductInterface::class,
|
||||
$product,
|
||||
'visibility',
|
||||
$storeId
|
||||
));
|
||||
|
||||
$this->assertFalse($scopeOverriddenValue->containsValue(
|
||||
ProductInterface::class,
|
||||
$product,
|
||||
'tax_class_id',
|
||||
$storeId
|
||||
));
|
||||
|
||||
$this->assertFalse($scopeOverriddenValue->containsValue(
|
||||
ProductInterface::class,
|
||||
$product,
|
||||
'status',
|
||||
$storeId
|
||||
));
|
||||
$attributeCodeList = ['visibility', 'tax_class_id', 'status', 'short_description', 'description',
|
||||
'url_key', 'meta_title', 'meta_keywords', 'meta_description'];
|
||||
foreach ($attributeCodeList as $attributeCode) {
|
||||
$this->assertFalse($scopeOverriddenValue->containsValue(
|
||||
ProductInterface::class,
|
||||
$product,
|
||||
$attributeCode,
|
||||
$storeId
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,9 +26,9 @@ use Magento\TestFramework\TestCase\WebapiAbstract;
|
||||
*/
|
||||
class GroupRepositoryTest extends WebapiAbstract
|
||||
{
|
||||
const SERVICE_NAME = "customerGroupRepositoryV1";
|
||||
const SERVICE_VERSION = "V1";
|
||||
const RESOURCE_PATH = "/V1/customerGroups";
|
||||
private const SERVICE_NAME = "customerGroupRepositoryV1";
|
||||
private const SERVICE_VERSION = "V1";
|
||||
private const RESOURCE_PATH = "/V1/customerGroups";
|
||||
|
||||
/**
|
||||
* @var GroupRegistry
|
||||
@@ -512,16 +512,27 @@ class GroupRepositoryTest extends WebapiAbstract
|
||||
|
||||
self::assertEquals($groupId, $this->_webApiCall($serviceInfo, $requestData)[CustomerGroup::ID]);
|
||||
|
||||
$group = $this->groupRepository->getById($groupId);
|
||||
self::assertEquals($groupData[CustomerGroup::CODE], $group->getCode(), 'The group code did not change.');
|
||||
$serviceInfo = [
|
||||
'rest' => [
|
||||
'resourcePath' => self::RESOURCE_PATH . "/$groupId",
|
||||
'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
|
||||
],
|
||||
];
|
||||
|
||||
$group = $this->_webApiCall($serviceInfo);
|
||||
self::assertEquals(
|
||||
$groupData[CustomerGroup::CODE],
|
||||
$group['code'],
|
||||
'The group code did not change.'
|
||||
);
|
||||
self::assertEquals(
|
||||
$groupData[CustomerGroup::TAX_CLASS_ID],
|
||||
$group->getTaxClassId(),
|
||||
$group['tax_class_id'],
|
||||
'The group tax class id did not change'
|
||||
);
|
||||
self::assertEquals(
|
||||
['1'],
|
||||
$group->getExtensionAttributes()->getExcludeWebsiteIds(),
|
||||
$group['extension_attributes']['exclude_website_ids'],
|
||||
'The group excluded websites do not match.'
|
||||
);
|
||||
}
|
||||
@@ -850,48 +861,6 @@ class GroupRepositoryTest extends WebapiAbstract
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that updating an existing group with excluded website works via SOAP.
|
||||
*/
|
||||
public function testUpdateGroupWithExcludedWebsiteSoap(): void
|
||||
{
|
||||
$this->_markTestAsSoapOnly();
|
||||
$group = $this->customerGroupFactory->create();
|
||||
$group->setId(null);
|
||||
$group->setCode('New Group with Exclude SOAP');
|
||||
$group->setTaxClassId(3);
|
||||
$groupId = $this->createGroup($group);
|
||||
|
||||
$serviceInfo = [
|
||||
'soap' => [
|
||||
'service' => self::SERVICE_NAME,
|
||||
'serviceVersion' => self::SERVICE_VERSION,
|
||||
'operation' => 'customerGroupRepositoryV1Save',
|
||||
],
|
||||
];
|
||||
|
||||
$groupData = [
|
||||
CustomerGroup::ID => $groupId,
|
||||
CustomerGroup::CODE => 'Updated Group with Exclude SOAP',
|
||||
'taxClassId' => 3,
|
||||
'extension_attributes' => ['exclude_website_ids' => ['1']]
|
||||
];
|
||||
$this->_webApiCall($serviceInfo, ['group' => $groupData]);
|
||||
|
||||
$group = $this->groupRepository->getById($groupId);
|
||||
self::assertEquals($groupData[CustomerGroup::CODE], $group->getCode(), 'The group code did not change.');
|
||||
self::assertEquals(
|
||||
$groupData['taxClassId'],
|
||||
$group->getTaxClassId(),
|
||||
'The group tax class id did not change'
|
||||
);
|
||||
self::assertEquals(
|
||||
['1'],
|
||||
$group->getExtensionAttributes()->getExcludeWebsiteIds(),
|
||||
'The group excluded websites do not match.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that updating a non-existing group throws an exception via SOAP.
|
||||
*/
|
||||
|
||||
+4
-18
@@ -587,6 +587,7 @@ class MediaGalleryTest extends ResolverCacheAbstract
|
||||
* @param ProductInterface $product
|
||||
* @return void
|
||||
* @throws \Zend_Cache_Exception
|
||||
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
|
||||
*/
|
||||
private function assertCacheIdIsNotOrphanedInTagsForProduct(ProductInterface $product)
|
||||
{
|
||||
@@ -594,24 +595,9 @@ class MediaGalleryTest extends ResolverCacheAbstract
|
||||
$cacheLowLevelFrontend = $this->graphQlResolverCache->getLowLevelFrontend();
|
||||
$cacheIdPrefix = $cacheLowLevelFrontend->getOption('cache_id_prefix');
|
||||
$cacheBackend = $cacheLowLevelFrontend->getBackend();
|
||||
|
||||
$this->assertNotContains(
|
||||
$cacheIdPrefix . $cacheKey,
|
||||
$cacheBackend->getIdsMatchingTags([
|
||||
$cacheIdPrefix . 'GRAPHQL_QUERY_RESOLVER_RESULT'
|
||||
]),
|
||||
'Cache id is still present in GRAPHQL_QUERY_RESOLVER_RESULT tag file after invalidation'
|
||||
);
|
||||
|
||||
$this->assertNotContains(
|
||||
$cacheIdPrefix . $cacheKey,
|
||||
$cacheBackend->getIdsMatchingTags([
|
||||
$cacheIdPrefix . 'GQL_MEDIA_GALLERY_' . strtoupper($product->getSku()),
|
||||
]),
|
||||
sprintf(
|
||||
'Cache id is still present in GQL_MEDIA_GALLERY_%s tag file after invalidation',
|
||||
strtoupper($product->getSku())
|
||||
)
|
||||
$this->assertFalse(
|
||||
$this->graphQlResolverCache->test($cacheIdPrefix . 'GRAPHQL_QUERY_RESOLVER_RESULT'),
|
||||
'Cache id is still present after invalidation'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -753,7 +753,7 @@ QUERY;
|
||||
{
|
||||
$query = <<<QUERY
|
||||
{
|
||||
products(filter: {sku: {eq: "${productSku}"}}) {
|
||||
products(filter: {sku: {eq: "{$productSku}"}}) {
|
||||
items {
|
||||
name
|
||||
... on CustomizableProductInterface {
|
||||
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
*
|
||||
* Copyright 2023 Adobe
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* NOTICE: All information contained herein is, and remains
|
||||
* the property of Adobe and its suppliers, if any. The intellectual
|
||||
* and technical concepts contained herein are proprietary to Adobe
|
||||
* and its suppliers and are protected by all applicable intellectual
|
||||
* property laws, including trade secret and copyright laws.
|
||||
* Dissemination of this information or reproduction of this material
|
||||
* is strictly forbidden unless prior written permission is obtained
|
||||
* from Adobe.
|
||||
* ************************************************************************
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\Quote\Guest;
|
||||
|
||||
use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId;
|
||||
use Magento\GraphQl\Quote\GetQuoteItemIdByReservedQuoteIdAndSku;
|
||||
use Magento\TestFramework\Helper\Bootstrap;
|
||||
use Magento\TestFramework\TestCase\GraphQlAbstract;
|
||||
|
||||
/**
|
||||
* Test for getting is_virtual from cart
|
||||
*/
|
||||
class GetShippingAddressWhenCartIsVirtualTest extends GraphQlAbstract
|
||||
{
|
||||
/**
|
||||
* @var GetMaskedQuoteIdByReservedOrderId
|
||||
*/
|
||||
private $getMaskedQuoteIdByReservedOrderId;
|
||||
|
||||
/**
|
||||
* @var GetQuoteItemIdByReservedQuoteIdAndSku
|
||||
*/
|
||||
private $getQuoteItemIdByReservedQuoteIdAndSku;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$objectManager = Bootstrap::getObjectManager();
|
||||
$this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
|
||||
$this->getQuoteItemIdByReservedQuoteIdAndSku = $objectManager->get(
|
||||
GetQuoteItemIdByReservedQuoteIdAndSku::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
|
||||
* @magentoApiDataFixture Magento/Catalog/_files/product_virtual.php
|
||||
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
|
||||
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_virtual_product.php
|
||||
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php
|
||||
*/
|
||||
public function testGetShippingAddressForVirtualCart()
|
||||
{
|
||||
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
|
||||
$query = $this->getQuery($maskedQuoteId);
|
||||
$response = $this->graphQlQuery($query);
|
||||
$itemId = $this->getQuoteItemIdByReservedQuoteIdAndSku->execute('test_quote', 'simple_product');
|
||||
|
||||
$expectedShippingAddressData = [
|
||||
'firstname' => 'John',
|
||||
'lastname' => 'Smith',
|
||||
'company' => 'CompanyName',
|
||||
'street' => [
|
||||
'Green str, 67'
|
||||
],
|
||||
'city' => 'CityM',
|
||||
'region' => [
|
||||
'code' => 'AL',
|
||||
'label' => 'Alabama',
|
||||
],
|
||||
'postcode' => '75477',
|
||||
'country' => [
|
||||
'code' => 'US',
|
||||
'label' => 'US',
|
||||
],
|
||||
'telephone' => '3468676',
|
||||
'__typename' => 'ShippingCartAddress',
|
||||
];
|
||||
|
||||
$this->assertArrayHasKey('cart', $response);
|
||||
$this->assertArrayHasKey('is_virtual', $response['cart']);
|
||||
$this->assertFalse($response['cart']['is_virtual']);
|
||||
$this->assertArrayHasKey('shipping_addresses', $response['cart']);
|
||||
$this->assertEquals($expectedShippingAddressData, current($response['cart']['shipping_addresses']));
|
||||
|
||||
$query2 = $this->getQueryForItemRemove($maskedQuoteId, $itemId);
|
||||
$this->graphQlMutation($query2);
|
||||
$response = $this->graphQlQuery($query);
|
||||
|
||||
$this->assertArrayHasKey('cart', $response);
|
||||
$this->assertArrayHasKey('is_virtual', $response['cart']);
|
||||
$this->assertTrue($response['cart']['is_virtual']);
|
||||
$this->assertArrayHasKey('shipping_addresses', $response['cart']);
|
||||
$this->assertFalse(current($response['cart']['shipping_addresses']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $maskedQuoteId
|
||||
* @return string
|
||||
*/
|
||||
private function getQuery(string $maskedQuoteId): string
|
||||
{
|
||||
return <<<QUERY
|
||||
{
|
||||
cart(cart_id: "$maskedQuoteId") {
|
||||
is_virtual
|
||||
total_quantity
|
||||
items {
|
||||
id
|
||||
product {
|
||||
name
|
||||
sku
|
||||
}
|
||||
quantity
|
||||
errors {
|
||||
code
|
||||
message
|
||||
}
|
||||
}
|
||||
shipping_addresses {
|
||||
firstname
|
||||
lastname
|
||||
company
|
||||
street
|
||||
city
|
||||
region
|
||||
{
|
||||
code
|
||||
label
|
||||
}
|
||||
postcode
|
||||
country
|
||||
{
|
||||
code
|
||||
label
|
||||
}
|
||||
telephone
|
||||
__typename
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $maskedQuoteId
|
||||
* @param int $itemId
|
||||
* @return string
|
||||
*/
|
||||
private function getQueryForItemRemove(string $maskedQuoteId, int $itemId): string
|
||||
{
|
||||
return <<<QUERY
|
||||
mutation {
|
||||
removeItemFromCart(
|
||||
input: {
|
||||
cart_id: "{$maskedQuoteId}"
|
||||
cart_item_id: {$itemId}
|
||||
}
|
||||
) {
|
||||
cart {
|
||||
items {
|
||||
quantity
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
}
|
||||
+3
@@ -211,5 +211,8 @@ return [
|
||||
Magento\Framework\Escaper::class => [
|
||||
'escaper' => null, // Note: just lazy loading without a Proxy. Should use DI instead, but not big deal
|
||||
],
|
||||
Magento\Framework\App\State\Interceptor::class => [
|
||||
'_areaCode' => null, // Note: _areaCode gets set after construction.
|
||||
],
|
||||
],
|
||||
];
|
||||
+725
@@ -0,0 +1,725 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
/* These classes are skipped completely during comparison. */
|
||||
return [
|
||||
'*' => [
|
||||
// phpcs:disable Generic.Files.LineLength.TooLong
|
||||
// list of the latest failures started
|
||||
Magento\Sales\Api\Data\ShippingAssignmentInterfaceFactory::class => null,
|
||||
Magento\Sales\Model\Order\ShippingBuilderFactory::class => null,
|
||||
Magento\Sales\Model\Order\ShippingAssignmentBuilder::class => null,
|
||||
// list of the latest failures ended
|
||||
Magento\Framework\Translate\Inline::class => null,
|
||||
Magento\Framework\Json\Encoder::class => null,
|
||||
Magento\Framework\Lock\Proxy::class => null,
|
||||
Magento\Framework\Indexer\Table\Strategy::class => null,
|
||||
Magento\Framework\GraphQl\Query\Fields::class => null,
|
||||
Magento\Framework\Stdlib\ArrayManager::class => null,
|
||||
Magento\Framework\Reflection\MethodsMap::class => null,
|
||||
Magento\Framework\Reflection\DataObjectProcessor::class => null,
|
||||
Magento\Framework\Api\DataObjectHelper::class => null,
|
||||
Magento\Framework\Url\QueryParamsResolver::class => null,
|
||||
Magento\Framework\Acl\Data\Cache::class => null,
|
||||
Magento\Framework\View\Asset\PreProcessor\Helper\Sort::class => null,
|
||||
Magento\Framework\Filter\FilterManager::class => null,
|
||||
Magento\Framework\Validator\Factory::class => null,
|
||||
Magento\Framework\Translate\Inline\ConfigInterface\Proxy::class => null,
|
||||
Magento\Framework\Json\Helper\Data::class => null,
|
||||
Magento\Framework\Api\ExtensionAttribute\JoinProcessor::class => null,
|
||||
Magento\Framework\Reflection\ExtensionAttributesProcessor\Proxy::class => null,
|
||||
Magento\Framework\Api\ImageProcessor::class => null,
|
||||
Magento\Framework\Model\ResourceModel\Db\VersionControl\Metadata::class => null,
|
||||
Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot::class => null,
|
||||
Magento\Framework\Indexer\IndexerRegistry::class => null,
|
||||
Magento\Framework\Session\SessionMaxSizeConfig::class => null,
|
||||
Magento\Framework\Module\Manager::class => null,
|
||||
Magento\Framework\MessageQueue\Code\Generator\Config\RemoteServiceReader\Communication::class => null,
|
||||
Magento\Framework\Webapi\ServiceInputProcessor::class => null,
|
||||
Magento\Framework\MessageQueue\Publisher\Config\RemoteService\Reader::class => null,
|
||||
Magento\Framework\Registry::class => null,
|
||||
Magento\Framework\Module\ModuleList::class => null,
|
||||
Magento\Framework\Session\Storage::class => null,
|
||||
Magento\Framework\Translate\Inline\Proxy::class => null,
|
||||
Magento\Framework\App\View::class => null,
|
||||
Magento\Framework\App\Action\Context::class => null,
|
||||
Magento\Framework\Event\Config\Data::class => null,
|
||||
Magento\Framework\App\AreaList::class => null,
|
||||
Magento\Framework\App\DeploymentConfig::class => null,
|
||||
Magento\Framework\App\Cache\Frontend\Pool::class => null,
|
||||
Magento\Framework\App\Cache\Type\FrontendPool::class => null,
|
||||
Magento\Framework\App\DeploymentConfig\Writer::class => null,
|
||||
Magento\Framework\View\Design\FileResolution\Fallback\TemplateFile::class => null,
|
||||
Magento\Framework\Module\Dir\Reader::class => null,
|
||||
Magento\Framework\Module\PackageInfo::class => null,
|
||||
Magento\Framework\App\Language\Dictionary::class => null,
|
||||
Magento\Framework\ObjectManager\ConfigInterface::class => null,
|
||||
Magento\Framework\App\Cache\Type\Config::class => null,
|
||||
Magento\Framework\Interception\PluginListGenerator::class => null,
|
||||
Magento\Framework\View\FileSystem::class => null,
|
||||
Magento\Framework\App\Config\FileResolver::class => null,
|
||||
Magento\Framework\App\Request\Http\Proxy::class => null,
|
||||
Magento\Framework\Event\Config\Reader\Proxy::class => null,
|
||||
Magento\Framework\View\Asset\Source::class => null,
|
||||
Magento\Framework\Translate\ResourceInterface\Proxy::class => null,
|
||||
Magento\Framework\Locale\Resolver\Proxy::class => null,
|
||||
Magento\Framework\Locale\Resolver::class => null,
|
||||
Magento\Framework\App\Http\Context::class => null,
|
||||
Magento\Framework\View\Design\Fallback\RulePool::class => null,
|
||||
Magento\Framework\View\Asset\Repository::class => null,
|
||||
Magento\Framework\HTTP\Header::class => null,
|
||||
Magento\Framework\App\Route\Config::class => null,
|
||||
Magento\Framework\App\Cache\Proxy::class => null,
|
||||
Magento\Framework\Translate::class => null,
|
||||
Magento\Framework\View\Asset\Minification::class => null,
|
||||
Magento\Framework\Url::class => null,
|
||||
Magento\Framework\HTTP\PhpEnvironment\RemoteAddress::class => null,
|
||||
Magento\Framework\ObjectManager\DefinitionInterface::class => null,
|
||||
Magento\Framework\App\ResourceConnection::class => null,
|
||||
Magento\Framework\App\ResourceConnection\Interceptor::class => null,
|
||||
Magento\Framework\Session\SaveHandler::class => null, // TODO: check this
|
||||
Magento\Framework\Css\PreProcessor\Adapter\CssInliner::class => null,
|
||||
Magento\Framework\Config\Scope::class => null,
|
||||
Magento\Framework\App\ResourceConnection\Config::class => null,
|
||||
Magento\Framework\Cache\Config\Data::class => null,
|
||||
Magento\Framework\Model\ActionValidator\RemoveAction::class => null,
|
||||
Magento\Framework\Session\Generic::class => null,
|
||||
Magento\Framework\Validator\EmailAddress::class => null,
|
||||
Magento\Sales\Model\Order\Email\Container\Template::class => null,
|
||||
Magento\Sales\Model\Order\Email\Container\OrderIdentity::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\OrderSender::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\OrderCommentSender::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\InvoiceCommentSender::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\InvoiceSender::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\CreditmemoCommentSender::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\CreditmemoSender::class => null,
|
||||
Magento\Sales\Model\Order\ItemRepository::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order\Relation::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order\Handler\Address::class => null,
|
||||
Magento\Sales\Model\OrderIncrementIdChecker::class => null,
|
||||
Magento\Sales\Api\Data\OrderSearchResultInterfaceFactory::class => null,
|
||||
Magento\Sales\Api\Data\OrderExtensionFactory::class => null,
|
||||
Magento\Sales\Model\OrderRepository::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order\Payment::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Attribute::class => null,
|
||||
Magento\SalesRule\Model\DeltaPriceRound::class => null,
|
||||
Magento\SalesRule\Helper\CartFixedDiscount::class => null,
|
||||
Magento\SalesRule\Api\Data\RuleInterfaceFactory::class => null,
|
||||
Magento\SalesRule\Api\Data\ConditionInterfaceFactory::class => null,
|
||||
Magento\SalesRule\Api\Data\RuleLabelInterfaceFactory::class => null,
|
||||
Magento\SalesRule\Model\Converter\ToDataModel::class => null,
|
||||
Magento\SalesRule\Model\Converter\ToModel::class => null,
|
||||
Magento\SalesRule\Api\Data\RuleSearchResultInterfaceFactory::class => null,
|
||||
Magento\SalesRule\Model\RuleRepository::class => null,
|
||||
Magento\SalesRule\Model\RuleFactory::class => null,
|
||||
Magento\SalesSequence\Model\MetaFactory::class => null,
|
||||
Magento\SalesSequence\Model\ProfileFactory::class => null,
|
||||
Magento\SalesSequence\Model\ResourceModel\Profile::class => null,
|
||||
Magento\SalesSequence\Model\ResourceModel\Meta::class => null,
|
||||
Magento\SalesSequence\Model\SequenceFactory::class => null,
|
||||
Magento\SalesSequence\Model\Manager::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Collection\Interceptor::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Quote\Collection\Interceptor::class => null,
|
||||
Magento\Quote\Api\Data\ProductOptionInterfaceFactory::class => null,
|
||||
Magento\Quote\Model\Quote\Item\Interceptor::class => null,
|
||||
Magento\Quote\Model\Quote\Address\Interceptor::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Quote::class => null,
|
||||
Magento\Quote\Model\QuoteIdToMaskedQuoteId::class => null,
|
||||
Magento\Quote\Model\Quote\Address\Total\Collector::class => null,
|
||||
Magento\Quote\Model\Quote\TotalsCollectorList::class => null,
|
||||
Magento\Quote\Model\Quote\TotalsCollector::class => null,
|
||||
Magento\Quote\Model\Quote::class => null,
|
||||
Magento\Quote\Model\Quote\ProductOptionFactory::class => null,
|
||||
Magento\Quote\Api\Data\ProductOptionExtensionFactory::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableRowSizeEstimator::class => null,
|
||||
Magento\Catalog\Model\Indexer\Price\BatchSizeManagement::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\CompositeProductRelationsCalculator::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\CompositeProductRowSizeEstimator::class => null,
|
||||
Magento\Catalog\Model\Indexer\Price\CompositeProductBatchSizeManagement::class => null,
|
||||
Magento\Catalog\Model\Indexer\Product\Price\TableMaintainer::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructureFactory::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Attribute\Backend\Tierprice::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\TierPrice::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\CompositeProductBatchSizeAdjuster::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\BatchSizeCalculator::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection::class => null,
|
||||
Magento\Catalog\Model\Product\Attribute\Repository::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product::class => null,
|
||||
Magento\Catalog\Model\ProductRepository::class => null,
|
||||
Magento\Catalog\Model\Product\Type::class => null,
|
||||
Magento\Catalog\Model\Product\Link::class => null,
|
||||
Magento\Customer\Model\Indexer\AttributeProvider::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Customer::class => null,
|
||||
Magento\Customer\Model\ResourceModel\CustomerRepository::class => null,
|
||||
Magento\Customer\Model\Session\Validators\CutoffValidator::class => null,
|
||||
Magento\Customer\Model\Customer::class => null,
|
||||
Magento\Customer\Model\Session\SessionCleaner::class => null,
|
||||
Magento\Customer\Model\ResourceModel\AddressRepository::class => null,
|
||||
Magento\Customer\Model\CustomerRegistry::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Address\Relation::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Address::class => null,
|
||||
Magento\Customer\Model\AttributeMetadataConverter::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerMetadata::class => null,
|
||||
Magento\Customer\Model\Metadata\AttributeMetadataCache::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerCachedMetadata::class => null,
|
||||
Magento\Customer\Model\Config\Share::class => null,
|
||||
Magento\Customer\Model\Session\Proxy::class => null,
|
||||
Magento\Customer\Model\Delegation\Storage::class => null,
|
||||
Magento\Customer\Model\ResourceModel\GroupRepository::class => null,
|
||||
Magento\Customer\Helper\View::class => null,
|
||||
Magento\Customer\Model\Authorization\CustomerSessionUserContext::class => null,
|
||||
Magento\Customer\Model\Authentication::class => null,
|
||||
Magento\Customer\Model\Session::class => null,
|
||||
Magento\Customer\Model\AddressRegistry::class => null,
|
||||
Magento\Customer\Model\AttributeMetadataDataProvider::class => null,
|
||||
Magento\Customer\Model\AccountConfirmation::class => null,
|
||||
Magento\Customer\Model\AccountManagement::class => null,
|
||||
Magento\Customer\Model\Plugin\CustomerFlushFormKey::class => null,
|
||||
Magento\Customer\Observer\LogLastLoginAtObserver::class => null,
|
||||
Magento\Customer\Model\Visitor\Proxy::class => null,
|
||||
Magento\Customer\Observer\LogLastLoginAtObserver::class => null,
|
||||
Magento\Customer\Api\CustomerRepositoryInterface\Proxy::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Attribute::class => null,
|
||||
Magento\Customer\Model\Address\Config::class => null,
|
||||
Magento\Indexer\Model\Indexer::class => null,
|
||||
Magento\Indexer\Model\Indexer\DependencyDecorator::class => null,
|
||||
Magento\Indexer\Model\Indexer\DeferredCacheContext::class => null,
|
||||
Magento\Indexer\Model\Indexer\DeferredCacheCleaner::class => null,
|
||||
Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\ExtractDataFromCategoryTree::class => null,
|
||||
Magento\Eav\Model\ResourceModel\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\VersionControl\Metadata::class => null,
|
||||
Magento\Eav\Plugin\Model\ResourceModel\Entity\Attribute::class => null,
|
||||
Magento\Store\Model\GroupRepository::class => null,
|
||||
Magento\Bundle\Model\CartItemProcessor::class => null,
|
||||
Magento\ConfigurableProduct\Model\Quote\Item\CartItemProcessor::class => null,
|
||||
Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price\OptionsSelectBuilder::class => null,
|
||||
Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class => null,
|
||||
Magento\Payment\Gateway\Config\ConfigFactory::class => null,
|
||||
Magento\Payment\Gateway\Data\Quote\AddressAdapterFactory::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Category::class => null,
|
||||
Magento\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\CollectionProcessor\FilterProcessor\CategoryFilter::class => null,
|
||||
Magento\Tax\Model\Quote\ToOrderConverter::class => null,
|
||||
Magento\Store\Model\WebsiteManagement::class => null,
|
||||
Magento\CatalogRule\Model\ResourceModel\Rule\Product\Price::class => null,
|
||||
Magento\CatalogRule\Model\Indexer\ProductPriceIndexModifier::class => null,
|
||||
Magento\InventoryConfigurableProduct\Pricing\Price\Indexer\BaseStockStatusSelectProcessor::class => null,
|
||||
Magento\InventoryConfigurableProduct\Pricing\Price\Indexer\OptionsIndexer::class => null,
|
||||
Magento\InventoryCatalog\Plugin\CatalogInventory\Model\Indexer\ModifySelectInProductPriceIndexFilter::class => null,
|
||||
Magento\Indexer\Model\Indexer\DeferCacheCleaning::class => null,
|
||||
|
||||
Magento\LoginAsCustomerAssistance\Model\IsAssistanceEnabled::class => null,
|
||||
Magento\LoginAsCustomerAssistance\Model\SetAssistance::class => null,
|
||||
Magento\LoginAsCustomerAssistance\Plugin\CustomerPlugin::class => null,
|
||||
Magento\Config\Model\Config\Processor\EnvironmentPlaceholder::class => null,
|
||||
Magento\GraphQlNewRelic\Plugin\ReportError::class => null,
|
||||
Magento\CatalogInventory\Model\StockRegistryProvider::class => null,
|
||||
Magento\CatalogInventory\Model\StockRegistry::class => null,
|
||||
Magento\CatalogInventory\Model\Indexer\ProductPriceIndexFilter::class => null,
|
||||
Magento\Tax\Model\Calculation::class => null,
|
||||
Magento\Tax\Model\TaxCalculation::class => null,
|
||||
Magento\SalesRule\Model\RulesApplier::class => null,
|
||||
Magento\OfflineShipping\Model\SalesRule\Calculator::class => null,
|
||||
Magento\OfflineShipping\Model\Quote\Address\FreeShipping::class => null,
|
||||
Magento\SalesRule\Model\Validator::class => null,
|
||||
Magento\User\Helper\Data::class => null,
|
||||
Magento\Authorization\Model\RoleFactory::class => null,
|
||||
Magento\User\Model\UserValidationRules::class => null,
|
||||
Magento\User\Model\Backend\Config\ObserverConfig::class => null,
|
||||
Magento\User\Model\ResourceModel\User::class => null,
|
||||
Magento\User\Model\Notificator::class => null,
|
||||
Magento\TestModuleCatalogInventoryCache\Plugin\PreventCachingPreloadedStockDataInToStockRegistry::class => null,
|
||||
Magento\Catalog\Model\CustomOptions\CustomOptionProcessor::class => null,
|
||||
'orderMetadata' => null,
|
||||
Magento\Payment\Api\Data\PaymentAdditionalInfoInterfaceFactory::class => null,
|
||||
Magento\InventoryInStorePickup\Model\ExtractPickupLocationAddressData::class => null,
|
||||
Magento\InventoryInStorePickupQuote\Model\ExtractQuoteAddressShippingAddressData::class => null,
|
||||
Magento\InventoryInStorePickupQuote\Model\GetShippingAddressData::class => null,
|
||||
Magento\InventoryInStorePickupQuote\Model\IsPickupLocationShippingAddress::class => null,
|
||||
Magento\InventoryInStorePickupQuote\Model\ToQuoteAddress::class => null,
|
||||
Magento\InventoryInStorePickupQuote\Model\GetWebsiteCodeByStoreId::class => null,
|
||||
Magento\InventoryInStorePickupQuote\Plugin\Quote\ReplaceShippingAddressForShippingAddressManagement::class => null,
|
||||
Magento\NegotiableQuote\Model\Plugin\Quote\Model\ShippingAssignmentPersisterPlugin::class => null,
|
||||
Magento\PurchaseOrder\Plugin\Quote\Model\QuoteRepositoryPlugin::class => null,
|
||||
Magento\Catalog\Model\Config::class => null,
|
||||
Magento\Downloadable\Model\Url\DomainValidator::class => null,
|
||||
Magento\Staging\Model\VersionManager::class => null,
|
||||
Magento\Staging\Model\Url\BaseUrlModifier::class => null,
|
||||
Magento\Staging\Model\Event\Manager::class => null,
|
||||
Magento\CatalogStaging\Plugin\Catalog\Model\Indexer\AbstractFlatState::class => null,
|
||||
Magento\Directory\Helper\Data::class => null,
|
||||
Magento\Store\Model\Address\Renderer::class => null,
|
||||
Magento\QuoteGraphQl\Plugin\ProductAttributesExtender::class => null,
|
||||
|
||||
Magento\Paypal\Plugin\TransparentSessionChecker::class => null,
|
||||
Magento\Backend\App\Area\FrontNameResolver::class => null,
|
||||
Magento\Backend\Helper\Data::class => null,
|
||||
Magento\GraphQl\Plugin\DisableSession::class => null,
|
||||
Magento\Tax\Model\TaxClass\Repository::class => null,
|
||||
Magento\JwtUserToken\Model\ResourceModel\FastStorageRevokedWrapper::class => null,
|
||||
Magento\Webapi\Model\Authorization\TokenUserContext::class => null,
|
||||
Magento\Authorization\Model\CompositeUserContext::class => null,
|
||||
Magento\Webapi\Model\WebapiRoleLocator::class => null,
|
||||
'CustomerAddressSnapshot' => null,
|
||||
'EavVersionControlSnapshot' => null,
|
||||
Magento\CustomerGraphQl\Model\Customer\ValidateCustomerData\ValidateEmail::class => null,
|
||||
Magento\CustomerGraphQl\Model\Customer\ValidateCustomerData::class => null,
|
||||
Magento\Catalog\Helper\Data::class => null,
|
||||
|
||||
Magento\Eav\Model\AttributeDataFactory::class => null,
|
||||
Magento\Checkout\Model\Session::class => null,
|
||||
|
||||
Magento\JwtUserToken\Model\ConfigurableJwtSettingsProvider::class => null,
|
||||
Magento\JwtUserToken\Model\Reader::class => null,
|
||||
|
||||
Magento\Bundle\Pricing\Price\TaxPrice::class => null,
|
||||
Magento\Customer\Observer\AfterAddressSaveObserver::class => null,
|
||||
Magento\LoginAsCustomer\Model\GetLoggedAsCustomerAdminId::class => null,
|
||||
Magento\CustomerGraphQl\Plugin\ClearCustomerSessionAfterRequest::class => null,
|
||||
Laminas\Uri\Uri::class => null,
|
||||
Magento\TestFramework\Interception\PluginList::class => null,
|
||||
// memory leak, wrong sql, potential issues
|
||||
Magento\Theme\Model\View\Design::class => null,
|
||||
Magento\RemoteStorage\Model\Config::class => null,
|
||||
Magento\Store\Model\Config\Processor\Fallback::class => null,
|
||||
Magento\Framework\Lock\LockBackendFactory::class => null,
|
||||
'customRemoteFilesystem' => null,
|
||||
'systemConfigQueryLocker' => null,
|
||||
Magento\Config\App\Config\Source\RuntimeConfigSource::class => null,
|
||||
'scopesConfigInitialDataProvider' => null,
|
||||
Magento\Developer\Model\Logger\Handler\Debug::class => null,
|
||||
Magento\Developer\Model\Logger\Handler\Syslog::class => null,
|
||||
Magento\Store\App\Config\Source\RuntimeConfigSource::class => null,
|
||||
Magento\Store\App\Config\Type\Scopes::class => null,
|
||||
Magento\TestFramework\App\Config::class => null,
|
||||
Magento\TestFramework\Request::class => null,
|
||||
Magento\TestFramework\ErrorLog\Logger::class => null,
|
||||
Magento\TestFramework\Db\Adapter\Mysql\Interceptor::class => null,
|
||||
Magento\TestFramework\Mail\Template\TransportBuilderMock::class => null,
|
||||
Magento\TestFramework\Api\Config\Reader\FileResolver::class => null,
|
||||
'translationConfigSourceAggregated' => null,
|
||||
Magento\Theme\Model\View\Design\Proxy::class => null,
|
||||
Magento\Translation\Model\Source\InitialTranslationSource\Proxy::class => null,
|
||||
Magento\Translation\App\Config\Type\Translation::class => null,
|
||||
Magento\Backend\App\Request\PathInfoProcessor\Proxy::class => null,
|
||||
Magento\MediaStorage\Helper\File\Storage\Database::class => null,
|
||||
Magento\Store\Model\StoreManager::class => null,
|
||||
Magento\Store\Model\StoreManager\Interceptor::class => null,
|
||||
Magento\TestFramework\Response::class => null,
|
||||
Magento\Store\Model\WebsiteRepository::class => null,
|
||||
Magento\Store\Model\StoreRepository::class => null,
|
||||
Magento\Store\Model\System\Store::class => null,
|
||||
Magento\AwsS3\Driver\CredentialsCache::class => null,
|
||||
Magento\Eav\Model\Config::class => null,
|
||||
'AssetPreProcessorPool' => null,
|
||||
Magento\GraphQl\Model\Query\ContextFactory::class => null,
|
||||
'viewFileMinifiedFallbackResolver' => null,
|
||||
/* AddUserInfoToContext has userContext changed by Magento\GraphQl\Model\Query\ContextFactory,
|
||||
* but we need to make this more robust in secure in case of unforeseen bugs.
|
||||
* resetState for userContext makes sense, but we need to make sure that it cannot copy current userContext. */
|
||||
Magento\CustomerGraphQl\Model\Context\AddUserInfoToContext::class => null, // FIXME: see above comment
|
||||
Magento\TestFramework\App\State::class => null,
|
||||
Magento\Framework\TestFramework\ApplicationStateComparator\SkipListAndFilterList::class => null, // Yes, our test uses mutable state itself :-)
|
||||
Magento\Framework\DB\Adapter\Pdo\Mysql\Interceptor::class => null,
|
||||
Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::class => null,
|
||||
Magento\Framework\Cache\Frontend\Adapter\Zend::class => null, // TODO: parentFrontends???
|
||||
Magento\Framework\Interception\PluginList\PluginList::class => null,
|
||||
Magento\Framework\App\Response\Http\Interceptor::class => null, // FIXME: Previous response needs to be reset for sure
|
||||
Magento\Framework\DB\Logger\LoggerProxy::class => null, // FIXME: might get fixed in ACPT-1034
|
||||
Magento\Framework\Session\SaveHandler\Redis::class => null, // TODO: make sure this is safe
|
||||
Magento\InventorySales\Model\IsProductSalableForRequestedQtyCondition\IsProductSalableForRequestedQtyConditionChain::class => null,
|
||||
Magento\InventorySales\Model\AreProductsSalableForRequestedQty::class => null,
|
||||
Magento\Customer\Model\GroupRegistry::class => null,
|
||||
Magento\Config\App\Config\Type\System::class => null,
|
||||
Magento\CatalogRule\Observer\RulePricesStorage::class => null,
|
||||
Magento\CatalogRule\Observer\PrepareCatalogProductCollectionPricesObserver::class => null,
|
||||
Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\QuoteItemQtyList::class => null,
|
||||
Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option::class => null,
|
||||
Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\StockItem::class => null,
|
||||
Magento\CatalogRule\Observer\ProcessFrontFinalPriceObserver::class => null,
|
||||
Magento\SalesRule\Model\Coupon\CodeLimitManager::class => null,
|
||||
Magento\SalesRule\Observer\CouponCodeValidation::class => null,
|
||||
Magento\CatalogInventory\Helper\Stock::class => null,
|
||||
Magento\Downloadable\Model\Product\Type::class => null,
|
||||
Magento\Bundle\Model\Product\Type::class => null,
|
||||
Magento\CatalogInventory\Observer\AddInventoryDataObserver::class => null,
|
||||
Magento\Downloadable\Model\Quote\Item\CartItemProcessor::class => null,
|
||||
Magento\Staging\Model\Update\VersionHistory::class => null,
|
||||
Magento\Staging\Model\UpdateRepository::class => null,
|
||||
Magento\GraphQlCache\Model\Plugin\Auth\TokenIssuer::class => null,
|
||||
Magento\GraphQlCache\Model\Plugin\Auth\TokenExtractor::class => null,
|
||||
Magento\Quote\Model\Quote\Relation::class => null,
|
||||
Magento\Quote\Model\QueryResolver::class => null,
|
||||
'QuoteRelationsComposite' => null,
|
||||
Magento\GraphQlCache\Model\Plugin\Auth\TokenIssuer::class => null,
|
||||
Magento\StoreGraphQl\Plugin\LocalizeEmail::class => null,
|
||||
// phpcs:enable Generic.Files.LineLength.TooLong
|
||||
],
|
||||
'*-fromConstructed' => [
|
||||
// phpcs:disable Generic.Files.LineLength.TooLong
|
||||
Magento\Customer\Model\Cache\GroupExcludedWebsiteCache::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Grid::class => null,
|
||||
Magento\Sales\Model\ResourceModel\GridPool::class => null,
|
||||
Magento\Sales\Api\Data\OrderExtension::class => null,
|
||||
Magento\Sales\Observer\GridSyncInsertObserver\Interceptor::class => null,
|
||||
Magento\Staging\Model\UpdateRepositoryCache::class => null,
|
||||
Magento\PageBuilder\Model\Filter\Template::class => null,
|
||||
Magento\PageBuilder\Plugin\Filter\TemplatePlugin::class => null,
|
||||
Magento\Customer\Api\Data\CustomerExtension::class => null,
|
||||
Magento\Framework\Css\PreProcessor\Adapter\CssInliner::class => null,
|
||||
Magento\Framework\TestFramework\ApplicationStateComparator\ObjectManager::class => null,
|
||||
Magento\RemoteStorage\Filesystem::class => null,
|
||||
Magento\Framework\App\Cache\Frontend\Factory::class => null,
|
||||
Magento\Framework\Config\Scope::class => null,
|
||||
Magento\TestFramework\ObjectManager\Config::class => null,
|
||||
Magento\Framework\ObjectManager\Definition\Runtime::class => null,
|
||||
Magento\Framework\Cache\LockGuardedCacheLoader::class => null,
|
||||
Magento\Config\App\Config\Type\System::class => null,
|
||||
Magento\Framework\View\Asset\PreProcessor\Pool::class => null,
|
||||
Magento\Framework\Xml\Parser::class => null, # TODO: why?!?! errorHandlerIsActive
|
||||
Magento\Framework\App\Area::class => null,
|
||||
Magento\Store\Model\Store\Interceptor::class => null,
|
||||
Magento\Framework\TestFramework\ApplicationStateComparator\Comparator::class => null, // Yes, our test uses mutable state itself :-)
|
||||
Magento\Framework\GraphQl\Query\QueryParser::class =>
|
||||
null, // TODO: Do we need to add a reset for when config changes?
|
||||
Magento\Framework\App\Http\Context\Interceptor::class => null,
|
||||
Magento\Framework\HTTP\LaminasClient::class => null,
|
||||
Magento\Customer\Model\GroupRegistry::class =>
|
||||
null, // FIXME: This looks like it needs _resetState or else it would be bug
|
||||
Magento\Framework\Model\ResourceModel\Db\VersionControl\Metadata::class => null,
|
||||
Magento\Framework\App\DeploymentConfig::class => null,
|
||||
Laminas\Uri\Uri::class => null,
|
||||
Magento\Framework\App\Cache\Frontend\Pool::class => null,
|
||||
Magento\TestFramework\App\State\Interceptor::class => null,
|
||||
Magento\TestFramework\App\MutableScopeConfig::class => null,
|
||||
Magento\TestFramework\Store\StoreManager::class => null,
|
||||
Magento\TestFramework\Workaround\Override\Config\RelationsCollector::class => null,
|
||||
Magento\Framework\Translate\Inline::class =>
|
||||
null, // TODO: Need to confirm that this gets reset when poison pill triggers
|
||||
Magento\Framework\Reflection\MethodsMap::class => null,
|
||||
Magento\Framework\Session\SaveHandler::class => null,
|
||||
Magento\Customer\Model\GroupRegistry::class => null, // FIXME: Needs _resetState for $registry
|
||||
Magento\Customer\Model\Group\Interceptor::class => null,
|
||||
Magento\Store\Model\Group\Interceptor::class => null,
|
||||
Magento\Directory\Model\Currency\Interceptor::class => null,
|
||||
Magento\Theme\Model\Theme\ThemeProvider::class => null, // Needs _resetState for themes
|
||||
Magento\Theme\Model\View\Design::class => null,
|
||||
Magento\Catalog\Model\Category\AttributeRepository::class =>
|
||||
null, // FIXME: Needs resetState OR reset when poison pill triggered.
|
||||
Magento\Framework\Search\Request\Cleaner::class => null, // FIXME: Needs resetState
|
||||
Magento\Catalog\Model\ResourceModel\Category\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Attribute\Backend\DefaultBackend\Interceptor::class => null,
|
||||
Magento\GraphQlCache\Model\Resolver\IdentityPool::class => null,
|
||||
Magento\Inventory\Model\Stock::class => null,
|
||||
Magento\InventorySales\Model\SalesChannel::class => null,
|
||||
Magento\InventoryApi\Api\Data\StockExtension::class => null,
|
||||
Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Eav\Attribute\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Category\Attribute\Backend\Image\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Attribute\Backend\Startdate\Interceptor::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Backend\Datetime\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Category\Attribute\Backend\Sortby\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Category\Attribute\Backend\LayoutUpdate\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Attribute\Backend\Customlayoutupdate\Interceptor::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Backend\Time\Created\Interceptor::class => null,
|
||||
Magento\Eav\Model\Entity\AttributeBackendTime\Updated\Interceptor::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Backend\Increment\Interceptor::class => null,
|
||||
Magento\Eav\Model\Entity\Interceptor::class => null,
|
||||
Magento\Framework\View\Asset\RepositoryMap::class =>
|
||||
null, // TODO: does this need to reset on poison pill trigger?
|
||||
Magento\Framework\Url\RouteParamsResolver\Interceptor::class => null,
|
||||
Magento\Theme\Model\Theme::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Category\Collection\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Category\Interceptor::class => null,
|
||||
Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree\Wrapper\NodeWrapper::class => null,
|
||||
Magento\Framework\Api\AttributeValue::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Interceptor::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Collection\Interceptor::class => null,
|
||||
Magento\Framework\Api\Search\SearchCriteria::class => null,
|
||||
Magento\Framework\Api\SortOrder::class => null,
|
||||
Magento\Framework\Api\Search\SearchResult::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Backend\Time\Updated\Interceptor::class => null,
|
||||
Magento\CatalogInventory\Model\Stock\Item\Interceptor::class => null,
|
||||
Magento\Framework\View\Asset\File::class => null,
|
||||
Magento\Customer\Model\Attribute\Interceptor::class => null,
|
||||
Magento\Framework\GraphQl\Schema\SchemaGenerator::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Customer::class => null,
|
||||
Magento\Framework\App\PageCache\Version::class => null,
|
||||
Magento\Framework\App\PageCache\Identifier::class => null,
|
||||
Magento\Framework\App\PageCache\Kernel::class => null,
|
||||
Magento\Translation\Model\Source\InitialTranslationSource::class => null,
|
||||
Magento\Framework\GraphQl\Schema\Type\Output\OutputMapper::class => null,
|
||||
Magento\Framework\GraphQl\Schema\Type\Input\InputMapper::class => null,
|
||||
Magento\Framework\Filesystem\DriverPool::class => null,
|
||||
Magento\Framework\Filesystem\Directory\WriteFactory::class => null,
|
||||
Magento\Catalog\Model\Product\Media\Config::class => null,
|
||||
Magento\Catalog\Model\Product\Type\Interceptor::class =>
|
||||
null, // Note: We may need to check to see if this needs to be reset when config changes
|
||||
Magento\ConfigurableProduct\Model\Product\Type\Configurable\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Product\Type\Simple\Interceptor::class => null,
|
||||
Magento\Customer\Model\Session\Storage::class =>
|
||||
null, // FIXME: race condition with Magento\Customer\Model\Session::_resetState()
|
||||
Magento\Framework\Module\Manager::class => null,
|
||||
Magento\Eav\Api\Data\AttributeExtension::class
|
||||
=> null, // FIXME: This needs to be fixed. is_pagebuilder_enabled 0 => null
|
||||
Magento\TestFramework\Event\Magento::class => null,
|
||||
Magento\Webapi\Model\Authorization\TokenUserContext::class => null, // Has good _resetState
|
||||
Magento\Store\Model\Website\Interceptor::class => null, // reset by poison pill
|
||||
Magento\Eav\Model\Entity\Type::class => null, // attribute types should be destroyed by poison pill
|
||||
Magento\Eav\Model\Entity\Attribute\Backend\DefaultBackend\Interceptor::class =>
|
||||
null, // attribute types should be destroyed by poison pill
|
||||
Magento\TestFramework\Mail\Template\TransportBuilderMock\Interceptor::class => null, // only for testing
|
||||
Magento\Customer\Model\Data\Customer::class =>
|
||||
null, // FIXME: looks like a bug. Why is this not destroyed?
|
||||
Magento\Customer\Model\Customer\Interceptor::class =>
|
||||
null, // FIXME: looks like a bug. Why is this not destroyed?
|
||||
Magento\Framework\ForeignKey\ObjectRelationProcessor\EnvironmentConfig::class =>
|
||||
null, // OK; shouldn't change outside of deployment
|
||||
Magento\Indexer\Model\Indexer\Interceptor::class =>
|
||||
null, // FIXME: looks like this needs to be reset ?
|
||||
Magento\Indexer\Model\Indexer\State::class =>
|
||||
null, // FIXME: looks like this needs to be reset ?
|
||||
Magento\Customer\Model\ResourceModel\Attribute\Collection\Interceptor::class =>
|
||||
null, // TODO: does this need to be fixed?
|
||||
Magento\Customer\Model\ResourceModel\Address\Attribute\Collection\Interceptor::class =>
|
||||
null, // TODO: why is this not getting destroyed?
|
||||
Magento\Customer\Model\Indexer\Address\AttributeProvider::class =>
|
||||
null, // TODO: I don't think this gets reset after poison pill, so it may need _resetState
|
||||
Magento\Customer\Model\Indexer\AttributeProvider::class =>
|
||||
null, // TODO: I don't think this gets reset after poison pill, so it may need _resetState
|
||||
Magento\Config\Model\Config\Structure\Data::class => null, // should be cleaned after poison pill
|
||||
Magento\Framework\Filter\Template\SignatureProvider::class =>
|
||||
null, // TODO: does this need _resetState?
|
||||
Magento\Customer\Model\ResourceModel\Address\Interceptor::class =>
|
||||
null, // customer_address_entity table info
|
||||
Magento\LoginAsCustomerAssistance\Model\IsAssistanceEnabled::class =>
|
||||
null, // FIXME: needs resetSate
|
||||
Magento\Quote\Model\Quote\Address\Total\Subtotal::class => null, // FIXME: these should not be reused.
|
||||
Magento\Quote\Model\Quote\Address\Total\Grand::class =>
|
||||
null, // FIXME: these should not be reused.
|
||||
Magento\SalesRule\Model\Quote\Address\Total\ShippingDiscount::class =>
|
||||
null, // FIXME: these should not be reused.
|
||||
Magento\Weee\Model\Total\Quote\WeeeTax::class => null, // FIXME: these should not be reused.
|
||||
Magento\Tax\Model\Sales\Total\Quote\Shipping\Interceptor::class => null, // FIXME: these should not be reused.
|
||||
Magento\Tax\Model\Sales\Total\Quote\Subtotal\Interceptor::class => null, // FIXME: these should not be reused.
|
||||
Magento\Ui\Config\Reader\FileResolver::class =>
|
||||
null, // TODO: confirm this gets reset from poison pill or is otherwise okay.
|
||||
Magento\Ui\Config\Converter::class =>
|
||||
null, // TODO: confirm this is cleaned when poison pill triggered
|
||||
Magento\SalesRule\Model\ResourceModel\Rule::class => null,
|
||||
Magento\SalesRule\Model\Plugin\QuoteConfigProductAttributes::class => null,
|
||||
Magento\QuoteGraphQl\Plugin\ProductAttributesExtender::class => null,
|
||||
|
||||
//Create Empty Cart
|
||||
Magento\Quote\Model\ResourceModel\Quote\QuoteIdMask::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Quote::class => null,
|
||||
Magento\Quote\Model\QuoteIdToMaskedQuoteId::class => null,
|
||||
Magento\Quote\Model\Cart\CustomerCartResolver::class => null,
|
||||
Magento\QuoteGraphQl\Model\Cart\CreateEmptyCartForGuest::class => null,
|
||||
Magento\Quote\Model\MaskedQuoteIdToQuoteId::class => null,
|
||||
Magento\SalesRule\Model\RulesApplier::class => null,
|
||||
Magento\OfflineShipping\Model\SalesRule\Calculator::class => null,
|
||||
Magento\Quote\Model\Quote\Address\Total\Shipping::class => null,
|
||||
Magento\SalesRule\Model\Validator::class => null,
|
||||
Magento\SalesRule\Model\Quote\Discount::class => null,
|
||||
Magento\Weee\Model\Total\Quote\Weee::class => null,
|
||||
Magento\Quote\Model\Quote\Address\Total\Collector::class => null,
|
||||
Magento\Quote\Model\Quote\Interceptor::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Quote\Address::class => null,
|
||||
Magento\Quote\Model\Quote\Address::class => null,
|
||||
Magento\Quote\Model\ShippingMethodManagement::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Quote\Item\Collection\Interceptor::class => null,
|
||||
Magento\Quote\Model\Quote\Address\Total::class => null,
|
||||
Laminas\Validator\ValidatorChain::class => null,
|
||||
Magento\Indexer\Model\Indexer\DeferCacheCleaning::class => null,
|
||||
Magento\ResourceConnections\App\DeploymentConfig::class => null,
|
||||
Magento\Staging\Model\StagingList::class => null,
|
||||
Magento\Staging\Model\ResourceModel\Update::class => null,
|
||||
Magento\AdobeCommerceEventsClient\Event\EventList::class => null,
|
||||
Magento\AdobeCommerceEventsClient\Event\Filter\EventFieldsFilter::class => null,
|
||||
Magento\AdobeCommerceEventsClient\Event\EventStorageWriter::class => null,
|
||||
Magento\TestModuleAdobeCommerceEvents\Plugin\Framework\ManagerInterfacePlugin::class => null,
|
||||
|
||||
Magento\Catalog\Model\Product\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Product\Attribute\Backend\Price\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Product\Attribute\Backend\Tierprice\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Product\Attribute\Backend\Boolean\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Product\Attribute\Backend\LayoutUpdate\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Product\Attribute\Backend\Stock\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Product\Attribute\Backend\Weight\Interceptor::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\CategoryLink::class => null,
|
||||
Magento\Catalog\Model\Category\Link\ReadHandler::class => null,
|
||||
Laminas\Validator\Uri::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Quote\Item::class => null,
|
||||
Magento\Quote\Model\Quote\Item::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Quote\Item\Option::class => null,
|
||||
Magento\Quote\Model\Quote\Item\Option::class => null,
|
||||
Magento\User\Model\User\Interceptor::class => null,
|
||||
Magento\Quote\Model\ShippingAssignment::class => null,
|
||||
Magento\Quote\Model\Shipping::class => null,
|
||||
Magento\NegotiableQuote\Model\NegotiableQuote\Interceptor::class => null,
|
||||
Magento\CatalogRule\Observer\RulePricesStorage::class => null,
|
||||
Magento\CatalogRule\Observer\PrepareCatalogProductCollectionPricesObserver::class => null,
|
||||
Magento\Quote\Api\Data\CartExtension::class => null,
|
||||
Magento\Catalog\Api\Data\ProductExtension::class => null,
|
||||
Magento\CatalogRule\Observer\ProcessFrontFinalPriceObserver::class => null,
|
||||
Magento\Quote\Api\Data\AddressExtension::class => null,
|
||||
Magento\TestModuleAdobeCommerceEvents\Plugin\Framework\ManagerInterfacePlugin::class => null,
|
||||
Magento\CatalogRule\Observer\ProcessFrontFinalPriceObserver\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Product\Type\Virtual\Interceptor::class => null,
|
||||
Magento\NegotiableQuote\Model\NegotiableQuote\Interceptor::class => null,
|
||||
Magento\CatalogInventory\Model\StockRegistryProvider::class => null,
|
||||
Magento\CatalogInventory\Model\StockRegistry::class => null,
|
||||
Magento\CatalogInventory\Helper\Stock::class => null,
|
||||
Magento\Catalog\Model\Product\Link\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Config::class => null,
|
||||
Magento\Bundle\Model\Product\Type\Interceptor::class => null,
|
||||
Magento\Bundle\Model\Product\LinksList::class => null,
|
||||
Magento\Bundle\Model\Product\OptionList::class => null,
|
||||
Magento\Bundle\Model\Option\SaveAction::class => null,
|
||||
Magento\Bundle\Model\OptionRepository::class => null,
|
||||
Magento\CatalogInventory\Model\AddStockStatusToCollection::class => null,
|
||||
Magento\Bundle\Model\ResourceModel\Option\Collection\Interceptor::class => null,
|
||||
Magento\Bundle\Model\Link::class => null,
|
||||
Magento\Bundle\Model\Option::class => null,
|
||||
Magento\Bundle\Model\BundleOption::class => null,
|
||||
Magento\Quote\Api\Data\ProductOptionExtension::class => null,
|
||||
Magento\Quote\Model\Quote\ProductOption::class => null,
|
||||
Magento\Catalog\Model\CategoryLink::class => null,
|
||||
Magento\ConfigurableProduct\Model\Product\Type\Configurable\OptionValue::class => null,
|
||||
Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection\Interceptor::class => null,
|
||||
Magento\ConfigurableProduct\Model\Quote\Item\ConfigurableItemOptionValue::class => null,
|
||||
Magento\Downloadable\Model\Product\Type\Interceptor::class => null,
|
||||
Magento\Downloadable\Model\LinkRepository::class => null,
|
||||
Magento\Downloadable\Model\SampleRepository::class => null,
|
||||
Magento\Downloadable\Model\Link::class => null,
|
||||
Magento\Downloadable\Model\ResourceModel\Sample\Collection\Interceptor::class => null,
|
||||
Magento\Downloadable\Model\Sample::class => null,
|
||||
Magento\Downloadable\Model\DownloadableOption::class => null,
|
||||
Magento\Payment\Model\MethodList::class => null,
|
||||
Magento\Quote\Model\PaymentMethodManagement::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Quote\Address\Rate::class => null,
|
||||
Magento\Framework\ObjectManager\TMap::class => null,
|
||||
Magento\Payment\Gateway\Config\ValueHandlerPool::class => null,
|
||||
Magento\Payment\Model\Method\Adapter::class => null,
|
||||
Magento\Tax\Model\Quote\GrandTotalDetailsPlugin::class => null,
|
||||
Magento\Quote\Model\BillingAddressManagement::class => null,
|
||||
Magento\QuoteGraphQl\Model\Cart\AssignBillingAddressToCart::class => null,
|
||||
Magento\NegotiableQuote\Plugin\Quote\Api\JoinNegotiableQuoteTotalsPlugin::class => null,
|
||||
Magento\Captcha\Helper\Data::class => null,
|
||||
Magento\Checkout\Model\CaptchaRateLimiter::class => null,
|
||||
Magento\Captcha\Model\DefaultModel::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Quote\Payment::class => null,
|
||||
Magento\CustomerGraphQl\Plugin\ClearCustomerSessionAfterRequest::class => null,
|
||||
Magento\Company\Plugin\Framework\Model\ActionValidator\RemoveActionPlugin::class => null,
|
||||
Magento\Sales\Model\Order\ItemRepository\Interceptor::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order\Interceptor::class => null,
|
||||
Magento\Sales\Model\Order\Address\Validator::class => null,
|
||||
Magento\Quote\Model\SubmitQuoteValidator::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\OrderSender::class => null,
|
||||
Magento\Catalog\Model\Indexer\Product\Price\DimensionModeConfiguration::class => null,
|
||||
Magento\Catalog\Model\Indexer\Product\Price\PriceTableResolver::class => null,
|
||||
Magento\Sales\Model\Order\Config::class => null,
|
||||
Magento\Sales\Model\Order\Interceptor::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order\Address::class => null,
|
||||
Magento\Sales\Model\Order\Address::class => null,
|
||||
Magento\Sales\Model\Order\CreditmemoFactory::class => null,
|
||||
Magento\Sales\Model\Order\Payment\Interceptor::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order\Item::class => null,
|
||||
Magento\Sales\Model\Order\Item\Interceptor::class => null,
|
||||
Magento\OfflinePayments\Model\Checkmo::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order\Status\Collection\Interceptor::class => null,
|
||||
Magento\Paypal\Model\Pro::class => null,
|
||||
Magento\Paypal\Model\Api\Nvp::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order\Invoice\Collection\Interceptor::class => null,
|
||||
Magento\CatalogSearch\Model\ResourceModel\EngineProvider::class => null,
|
||||
Magento\Catalog\Model\Indexer\Product\Price\DimensionCollectionFactory::class => null,
|
||||
Magento\Indexer\Model\Mview\View\State\Interceptor::class => null,
|
||||
Magento\Framework\Mview\View::class => null,
|
||||
Magento\Framework\Validator\EmailAddress::class => null,
|
||||
Magento\Framework\Amqp\ConfigPool::class => null,
|
||||
Magento\Framework\Amqp\ExchangeFactory::class => null,
|
||||
Magento\Framework\MessageQueue\MessageEncoder::class => null,
|
||||
Magento\Framework\MessageQueue\MessageValidator::class => null,
|
||||
Magento\Framework\MessageQueue\Bulk\Publisher::class => null,
|
||||
Magento\Framework\MessageQueue\Bulk\Rpc\Publisher::class => null,
|
||||
Magento\InventorySales\Plugin\InventoryReservationsApi\PreventAppendReservationOnNotManageItemsInStockPlugin::class => null,
|
||||
Magento\Framework\MessageQueue\ExchangeRepository::class => null,
|
||||
Magento\Framework\MessageQueue\Publisher::class => null,
|
||||
Magento\Framework\MessageQueue\Rpc\Publisher::class => null,
|
||||
Magento\Framework\MessageQueue\PublisherPool::class => null,
|
||||
Magento\InventoryIndexer\Plugin\InventorySales\EnqueueAfterPlaceReservationsForSalesEvent::class => null,
|
||||
Magento\Framework\Amqp\Config::class => null,
|
||||
Magento\Framework\Amqp\Exchange::class => null,
|
||||
PhpAmqpLib\Connection\AMQPStreamConnection::class => null,
|
||||
Magento\CatalogInventory\Model\Indexer\Stock\CacheCleaner::class => null,
|
||||
Magento\InventoryCatalogSearch\Plugin\CatalogSearch\Model\Indexer\ChildProductFilterByInventoryStockPlugin::class => null,
|
||||
Magento\InventoryElasticsearch\Plugin\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider\StockedProductFilterByInventoryStock::class => null,
|
||||
Magento\Widget\Model\ResourceModel\Layout\Update::class => null,
|
||||
Magento\Widget\Model\ResourceModel\Layout\Plugin::class => null,
|
||||
Magento\Sales\Model\Order\Address\Interceptor::class => null,
|
||||
Magento\OfflinePayments\Model\Checkmo\Interceptor::class => null,
|
||||
Magento\NegotiableQuote\Model\Restriction\Admin::class => null,
|
||||
Magento\AsynchronousOperations\Model\BulkManagement::class => null,
|
||||
Magento\SalesRule\Model\Service\CouponUsagePublisher::class => null,
|
||||
Magento\Paypal\Model\Api\Nvp\Interceptor::class => null,
|
||||
Magento\PurchaseOrder\Model\PurchaseOrder\LogManagement::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Collection\Interceptor::class => null,
|
||||
Magento\Customer\Model\Metadata\AddressMetadata::class => null,
|
||||
Magento\Customer\Model\Metadata\AddressCachedMetadata::class => null,
|
||||
Magento\Framework\App\ResourceConnection\Config::class => null,
|
||||
Magento\Framework\DB\Select\RendererProxy::class => null,
|
||||
Magento\Framework\DB\SelectFactory::class => null,
|
||||
Magento\Quote\Api\Data\CartItemExtension::class => null,
|
||||
Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\QuoteItemQtyList::class => null,
|
||||
Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option\Interceptor::class => null,
|
||||
Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\StockItem::class => null,
|
||||
Magento\SalesRule\Model\Coupon\CodeLimitManager::class => null,
|
||||
Magento\SalesRule\Observer\CouponCodeValidation::class => null,
|
||||
Magento\OfflineShipping\Model\Carrier\Flatrate::class => null,
|
||||
Magento\Quote\Model\Quote\Payment::class => null,
|
||||
Magento\Sales\Model\Order\Email\Container\Template::class => null,
|
||||
Magento\Sales\Model\Order\Email\Container\OrderIdentity::class => null,
|
||||
Magento\Customer\Model\Address\Config::class => null,
|
||||
Magento\Sales\Model\Order\Address\Renderer::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\OrderCommentSender::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\InvoiceCommentSender::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\InvoiceSender::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\CreditmemoCommentSender::class => null,
|
||||
Magento\Sales\Model\Order\Email\Sender\CreditmemoSender::class => null,
|
||||
Magento\Sales\Model\Order\Status::class => null,
|
||||
Magento\CatalogInventory\Model\Indexer\Stock\Action\Rows::class => null,
|
||||
Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\DefaultStock::class => null,
|
||||
Magento\ConfigurableProduct\Model\ResourceModel\Indexer\Stock\Configurable::class => null,
|
||||
Magento\Bundle\Model\ResourceModel\Indexer\Stock::class => null,
|
||||
Magento\GroupedProduct\Model\ResourceModel\Indexer\Stock\Grouped::class => null,
|
||||
Magento\Elasticsearch\Model\Adapter\BatchDataMapper\DataMapperResolver::class => null,
|
||||
Magento\Elasticsearch\Model\Adapter\Elasticsearch::class => null,
|
||||
Magento\Tax\Model\TaxClass\Source\Product::class => null,
|
||||
Magento\Framework\View\TemplateEnginePool::class => null,
|
||||
Magento\Framework\View\Element\Template\File\Resolver::class => null,
|
||||
Magento\Framework\View\Element\Template\File\Validator::class => null,
|
||||
Magento\Framework\View\Element\Template\Context::class => null,
|
||||
'validator' => null,
|
||||
'inlineTranslation' => null,
|
||||
Magento\Customer\Block\Address\Renderer\DefaultRenderer::class => null,
|
||||
Magento\Framework\View\Layout\ReaderPool::class => null,
|
||||
Magento\Framework\View\Layout\Reader\Block::class => null,
|
||||
Magento\Framework\View\Layout\Reader\UiComponent::class => null,
|
||||
Magento\PageCache\Observer\ProcessLayoutRenderElement::class => null,
|
||||
Magento\Staging\Model\Update::class => null,
|
||||
Magento\Staging\Model\Update\Flag::class => null,
|
||||
Magento\Catalog\Model\Category\Attribute\Source\Sortby::class => null,
|
||||
Magento\Config\App\Config\Source\EnvironmentConfigSource::class => null,
|
||||
// phpcs:enable Generic.Files.LineLength.TooLong
|
||||
],
|
||||
'' => [
|
||||
],
|
||||
];
|
||||
@@ -109,7 +109,7 @@ class SaveHandlerTest extends TestCase
|
||||
{
|
||||
/** @var OptionList $optionList */
|
||||
$optionList = $this->objectManager->create(OptionList::class);
|
||||
$product = $this->productRepository->get('bundle-product', true);
|
||||
$product = $this->productRepository->get('bundle-product', true, 0, true);
|
||||
|
||||
//set the first option
|
||||
$options = $this->setBundleProductOptionData();
|
||||
@@ -118,7 +118,7 @@ class SaveHandlerTest extends TestCase
|
||||
$product->setExtensionAttributes($extension);
|
||||
$product->save();
|
||||
|
||||
$product = $this->productRepository->get('bundle-product', true);
|
||||
$product = $this->productRepository->get('bundle-product', true, 0, true);
|
||||
$options = $optionList->getItems($product);
|
||||
$this->assertCount(1, $options);
|
||||
|
||||
@@ -138,7 +138,7 @@ class SaveHandlerTest extends TestCase
|
||||
$product->setExtensionAttributes($extension);
|
||||
$product->save();
|
||||
|
||||
$product = $this->productRepository->get('bundle-product', true);
|
||||
$product = $this->productRepository->get('bundle-product', true, 0, true);
|
||||
$options = $optionList->getItems($product);
|
||||
$this->assertCount(1, $options);
|
||||
}
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
*
|
||||
* Copyright 2023 Adobe
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* NOTICE: All information contained herein is, and remains
|
||||
* the property of Adobe and its suppliers, if any. The intellectual
|
||||
* and technical concepts contained herein are proprietary to Adobe
|
||||
* and its suppliers and are protected by all applicable intellectual
|
||||
* property laws, including trade secret and copyright laws.
|
||||
* Dissemination of this information or reproduction of this material
|
||||
* is strictly forbidden unless prior written permission is obtained
|
||||
* from Adobe.
|
||||
* ************************************************************************
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\Bundle\Model\ResourceModel\Selection;
|
||||
|
||||
use Magento\Catalog\Api\ProductRepositoryInterface;
|
||||
use Magento\TestFramework\Helper\Bootstrap;
|
||||
|
||||
class CollectionTest extends \Magento\Bundle\Model\Product\BundlePriceAbstract
|
||||
{
|
||||
/**
|
||||
* @var CollectionFactory
|
||||
*/
|
||||
protected $collectionFactory;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->collectionFactory = Bootstrap::getObjectManager()->create(CollectionFactory::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoIndexerDimensionMode catalog_product_price website
|
||||
* @magentoDataFixture Magento/Bundle/_files/PriceCalculator/dynamic_bundle_product.php
|
||||
* @magentoAppIsolation enabled
|
||||
* @magentoDbIsolation disabled
|
||||
* @group indexer_dimension
|
||||
* @dataProvider getTestCases
|
||||
*/
|
||||
public function testAddPriceDataWithIndexerDimensionMode(array $strategy, int $expectedCount)
|
||||
{
|
||||
$this->prepareFixture($strategy, 'bundle_product');
|
||||
|
||||
$productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
|
||||
$product = $productRepository->get('bundle_product', false, null, true);
|
||||
|
||||
/** @var Collection $collection */
|
||||
$collection = $this->collectionFactory->create();
|
||||
$collection->setStoreId(0);
|
||||
$collection->addPriceFilter($product, true);
|
||||
$items = $collection->getItems();
|
||||
|
||||
$this->assertCount($expectedCount, $items);
|
||||
}
|
||||
|
||||
public function getTestCases()
|
||||
{
|
||||
return [
|
||||
'Dynamic bundle product with three Simple products' => [
|
||||
'variation' => $this->getBundleConfiguration(),
|
||||
'expectedCount' => 1
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
private function getBundleConfiguration()
|
||||
{
|
||||
$optionsData = [
|
||||
[
|
||||
'title' => 'op1',
|
||||
'required' => true,
|
||||
'type' => 'checkbox',
|
||||
'links' => [
|
||||
[
|
||||
'sku' => 'simple1',
|
||||
'qty' => 3,
|
||||
'price' => 100,
|
||||
'price_type' => 0,
|
||||
],
|
||||
[
|
||||
'sku' => 'simple2',
|
||||
'qty' => 2,
|
||||
'price' => 100,
|
||||
'price_type' => 0,
|
||||
],
|
||||
[
|
||||
'sku' => 'simple3',
|
||||
'qty' => 1,
|
||||
'price' => 100,
|
||||
'price_type' => 0,
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
return [
|
||||
[
|
||||
'modifierName' => 'addSimpleProduct',
|
||||
'data' => [$optionsData]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,14 @@
|
||||
*/
|
||||
namespace Magento\Catalog\Helper\Product;
|
||||
|
||||
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
|
||||
use Magento\Customer\Model\Context;
|
||||
use Magento\Framework\Exception\LocalizedException;
|
||||
use Magento\Framework\Exception\NoSuchEntityException;
|
||||
use Magento\TestFramework\Fixture\AppIsolation;
|
||||
use Magento\TestFramework\Fixture\DataFixture;
|
||||
use Magento\TestFramework\Fixture\DataFixtureStorage;
|
||||
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
|
||||
|
||||
/**
|
||||
* @magentoAppArea frontend
|
||||
@@ -33,10 +40,15 @@ class ViewTest extends \PHPUnit\Framework\TestCase
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var DataFixtureStorage
|
||||
*/
|
||||
private $fixtures;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
|
||||
|
||||
$this->fixtures = DataFixtureStorageManager::getStorage();
|
||||
$this->objectManager->get(\Magento\Framework\App\State::class)->setAreaCode('frontend');
|
||||
$this->objectManager->get(\Magento\Framework\App\Http\Context::class)
|
||||
->setValue(Context::CONTEXT_AUTH, false, false);
|
||||
@@ -124,6 +136,71 @@ class ViewTest extends \PHPUnit\Framework\TestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Product meta description should be rendered on the product HTML sources as is, without changes or substitutions
|
||||
*
|
||||
* @return void
|
||||
* @throws LocalizedException
|
||||
* @throws NoSuchEntityException
|
||||
*/
|
||||
#[
|
||||
AppIsolation(true),
|
||||
DataFixture(ProductFixture::class, ['meta_description' => 'Product Meta Description'], 'p1'),
|
||||
]
|
||||
public function testProductMetaDescriptionShouldBeRenderedAsIs()
|
||||
{
|
||||
$product = $this->fixtures->get('p1');
|
||||
$metaDescription = '<meta name="description" content="Product Meta Description"/>';
|
||||
|
||||
$this->objectManager->get(\Magento\Framework\App\RequestInterface::class)->setParam('id', $product->getId());
|
||||
$this->_helper->prepareAndRender($this->page, $product->getId(), $this->_controller);
|
||||
|
||||
/** @var \Magento\TestFramework\Response $response */
|
||||
$response = $this->objectManager->get(\Magento\TestFramework\Response::class);
|
||||
|
||||
$this->page->renderResult($response);
|
||||
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$this->assertStringContainsString(
|
||||
$metaDescription,
|
||||
$response->getBody(),
|
||||
'Empty meta description should be rendered as is'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the product meta description is empty, it should not be substituted with any other data and should not be
|
||||
* rendered on the product HTML sources
|
||||
*
|
||||
* @return void
|
||||
* @throws LocalizedException
|
||||
* @throws NoSuchEntityException
|
||||
*/
|
||||
#[
|
||||
AppIsolation(true),
|
||||
DataFixture(ProductFixture::class, ['meta_description' => ''], 'p1'),
|
||||
]
|
||||
public function testEmptyProductMetaDescriptionShouldNotBeSubstitutedAndRendered()
|
||||
{
|
||||
$product = $this->fixtures->get('p1');
|
||||
$metaDescription = '<meta name="description" content="';
|
||||
|
||||
$this->objectManager->get(\Magento\Framework\App\RequestInterface::class)->setParam('id', $product->getId());
|
||||
$this->_helper->prepareAndRender($this->page, $product->getId(), $this->_controller);
|
||||
|
||||
/** @var \Magento\TestFramework\Response $response */
|
||||
$response = $this->objectManager->get(\Magento\TestFramework\Response::class);
|
||||
|
||||
$this->page->renderResult($response);
|
||||
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$this->assertStringNotContainsStringIgnoringCase(
|
||||
$metaDescription,
|
||||
$response->getBody(),
|
||||
'Empty meta description should not be substituted or rendered'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoAppIsolation enabled
|
||||
*/
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
*
|
||||
* Copyright 2023 Adobe
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* NOTICE: All information contained herein is, and remains
|
||||
* the property of Adobe and its suppliers, if any. The intellectual
|
||||
* and technical concepts contained herein are proprietary to Adobe
|
||||
* and its suppliers and are protected by all applicable intellectual
|
||||
* property laws, including trade secret and copyright laws.
|
||||
* Dissemination of this information or reproduction of this material
|
||||
* is strictly forbidden unless prior written permission is obtained
|
||||
* from Adobe.
|
||||
* ************************************************************************
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\Catalog\Model\Attribute\Backend\WebsiteSpecific;
|
||||
|
||||
use Magento\Catalog\Api\ProductRepositoryInterface;
|
||||
use Magento\Catalog\Model\Product\Attribute\Source\Status;
|
||||
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
|
||||
use Magento\Framework\MessageQueue\ConsumerFactory;
|
||||
use Magento\Store\Model\Store;
|
||||
use Magento\Store\Model\StoreManagerInterface;
|
||||
use Magento\TestFramework\Fixture\AppArea;
|
||||
use Magento\TestFramework\Fixture\DataFixture;
|
||||
use Magento\TestFramework\Fixture\DbIsolation;
|
||||
use Magento\TestFramework\Helper\Bootstrap;
|
||||
use Magento\TestFramework\MessageQueue\ClearQueueProcessor;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[
|
||||
AppArea('adminhtml'),
|
||||
]
|
||||
class ValueSynchronizerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var StoreManagerInterface
|
||||
*/
|
||||
private $storeManager;
|
||||
|
||||
/**
|
||||
* @var ProductRepositoryInterface
|
||||
*/
|
||||
private $productRepository;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$objectManager = Bootstrap::getObjectManager();
|
||||
$clearQueueProcessor = $objectManager->get(ClearQueueProcessor::class);
|
||||
$clearQueueProcessor->execute('catalog_website_attribute_value_sync');
|
||||
$this->storeManager = $objectManager->get(StoreManagerInterface::class);
|
||||
$this->productRepository = $objectManager->get(ProductRepositoryInterface::class);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$store = Bootstrap::getObjectManager()->create(Store::class);
|
||||
$store->load('store2', 'code');
|
||||
if ($store->getId()) {
|
||||
$store->delete();
|
||||
}
|
||||
}
|
||||
|
||||
#[
|
||||
DbIsolation(false),
|
||||
DataFixture(ProductFixture::class, ['sku' => 'prod1']),
|
||||
]
|
||||
public function testProcess(): void
|
||||
{
|
||||
$defaultStore = $this->storeManager->getStore('default');
|
||||
$product = $this->productRepository->get('prod1', true, $defaultStore->getId());
|
||||
$product->setStatus(Status::STATUS_DISABLED);
|
||||
$this->productRepository->save($product);
|
||||
|
||||
$secondStore = Bootstrap::getObjectManager()->create(Store::class);
|
||||
$secondStore->setName('Second store')
|
||||
->setCode('store2')
|
||||
->setStoreGroupId($defaultStore->getStoreGroupId())
|
||||
->setWebsiteId($defaultStore->getWebsiteId())
|
||||
->setIsActive(1);
|
||||
$secondStore->save();
|
||||
$this->storeManager->reinitStores();
|
||||
|
||||
$consumerFactory = Bootstrap::getObjectManager()->get(ConsumerFactory::class);
|
||||
$consumer = $consumerFactory->get('catalog_website_attribute_value_sync');
|
||||
$consumer->process(1);
|
||||
|
||||
$product = $this->productRepository->get('prod1', false, $secondStore->getId(), true);
|
||||
self::assertEquals(Status::STATUS_DISABLED, $product->getStatus());
|
||||
}
|
||||
}
|
||||
@@ -14,13 +14,18 @@ use Magento\Catalog\Model\ResourceModel\Category as CategoryResource;
|
||||
use Magento\Catalog\Model\ResourceModel\Category\Collection;
|
||||
use Magento\Catalog\Model\ResourceModel\Category\Tree;
|
||||
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
|
||||
use Magento\Catalog\Test\Fixture\Category as CategoryFixture;
|
||||
use Magento\Eav\Model\Entity\Attribute\Exception as AttributeException;
|
||||
use Magento\Framework\Exception\LocalizedException;
|
||||
use Magento\Framework\Exception\NoSuchEntityException;
|
||||
use Magento\Framework\Math\Random;
|
||||
use Magento\Framework\Url;
|
||||
use Magento\Store\Api\StoreRepositoryInterface;
|
||||
use Magento\Store\Model\Store;
|
||||
use Magento\Store\Model\StoreManagerInterface;
|
||||
use Magento\TestFramework\Fixture\DataFixture;
|
||||
use Magento\TestFramework\Fixture\DataFixtureStorage;
|
||||
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
|
||||
use Magento\TestFramework\Helper\Bootstrap;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
@@ -57,8 +62,14 @@ class CategoryTest extends TestCase
|
||||
/** @var CategoryRepositoryInterface */
|
||||
private $categoryRepository;
|
||||
|
||||
/**
|
||||
* @var DataFixtureStorage
|
||||
*/
|
||||
private $dataFixtureStorage;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @throws LocalizedException
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
@@ -69,6 +80,7 @@ class CategoryTest extends TestCase
|
||||
$this->_model = $this->objectManager->create(Category::class);
|
||||
$this->categoryResource = $this->objectManager->get(CategoryResource::class);
|
||||
$this->categoryRepository = $this->objectManager->get(CategoryRepositoryInterface::class);
|
||||
$this->dataFixtureStorage = DataFixtureStorageManager::getStorage();
|
||||
}
|
||||
|
||||
public function testGetUrlInstance(): void
|
||||
@@ -509,4 +521,21 @@ class CategoryTest extends TestCase
|
||||
|
||||
return $collection->getItemByColumnValue('name', $categoryName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws LocalizedException|\Exception
|
||||
*/
|
||||
#[
|
||||
DataFixture(CategoryFixture::class, as: 'category'),
|
||||
]
|
||||
public function testGetUrlAfterUpdate()
|
||||
{
|
||||
$category = $this->dataFixtureStorage->get('category');
|
||||
$category->setUrlKey('new-url');
|
||||
$category->setSaveRewritesHistory(true);
|
||||
$this->categoryResource->save($category);
|
||||
|
||||
$this->assertStringEndsWith('new-url.html', $category->getUrl());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\CatalogGraphQl\Model\Config;
|
||||
|
||||
use Magento\CatalogGraphQl\Model\Resolver\Products\Attributes\Collection as ProductsAttributesCollection;
|
||||
use Magento\Framework\Search\Request\Config as SearchRequestConfig;
|
||||
use Magento\TestFramework\Helper\Bootstrap;
|
||||
use Magento\TestFramework\Helper\CacheCleaner;
|
||||
|
||||
/**
|
||||
* @magentoDbIsolation disabled
|
||||
* @magentoAppArea graphql
|
||||
*/
|
||||
class ConfigTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var bool|null $isFixtureLoaded
|
||||
*/
|
||||
private ?bool $isFixtureLoaded = null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->isFixtureLoaded = false;
|
||||
CacheCleaner::cleanAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
if ($this->isFixtureLoaded) {
|
||||
$rollBackPath = __DIR__
|
||||
. '/../../../Catalog/_files/products_with_layered_navigation_attribute_store_options_rollback.php';
|
||||
require $rollBackPath;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to confirm that we don't load cached configuration before attribute existed
|
||||
*
|
||||
* @covers \Magento\Framework\Search\Request\Config
|
||||
* @return void
|
||||
* @magentoApiDataFixture Magento/Store/_files/store.php
|
||||
*/
|
||||
public function testAttributesChangeCleansSearchRequestConfigCache(): void
|
||||
{
|
||||
$objectManager = Bootstrap::getObjectManager();
|
||||
/** @var SearchRequestConfig $configInstance1 */
|
||||
$configInstance1 = $objectManager->create(SearchRequestConfig::class);
|
||||
$aggregations1 = $configInstance1->get('graphql_product_search_with_aggregation/aggregations');
|
||||
$this->assertArrayNotHasKey('test_configurable_bucket', $aggregations1);
|
||||
require __DIR__ . '/../../../Catalog/_files/products_with_layered_navigation_attribute_store_options.php';
|
||||
$this->isFixtureLoaded = true;
|
||||
/** @var SearchRequestConfig $configInstance2 */
|
||||
$configInstance2 = $objectManager->create(SearchRequestConfig::class);
|
||||
$aggregations2 = $configInstance2->get('graphql_product_search_with_aggregation/aggregations');
|
||||
$this->assertArrayHasKey('test_configurable_bucket', $aggregations2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to confirm that we don't load cached configuration before attribute existed
|
||||
*
|
||||
* @return void
|
||||
* @magentoApiDataFixture Magento/Store/_files/store.php
|
||||
*/
|
||||
public function testAttributesChangeCleansGraphQlConfigCache(): void
|
||||
{
|
||||
$objectManager = Bootstrap::getObjectManager();
|
||||
$this->resetStateProductsAttributesCollection($objectManager);
|
||||
$configInstance1 = $objectManager->create('Magento\Framework\GraphQl\Config\Data');
|
||||
$aggregations1 = $configInstance1->get('SimpleProduct/fields');
|
||||
$this->assertArrayNotHasKey('test_configurable', $aggregations1);
|
||||
require __DIR__ . '/../../../Catalog/_files/products_with_layered_navigation_attribute_store_options.php';
|
||||
$this->isFixtureLoaded = true;
|
||||
$this->resetStateProductsAttributesCollection($objectManager);
|
||||
$configInstance2 = $objectManager->create('Magento\Framework\GraphQl\Config\Data');
|
||||
$aggregations2 = $configInstance2->get('SimpleProduct/fields');
|
||||
$this->assertArrayHasKey('test_configurable', $aggregations2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to confirm that we don't load cached configuration before attribute existed
|
||||
*
|
||||
* @return void
|
||||
* @magentoApiDataFixture Magento/Store/_files/store.php
|
||||
* @magentoAppArea global
|
||||
*/
|
||||
public function testGraphQlConfigCacheShouldntBreakWhenLoadedByGlobalArea(): void
|
||||
{
|
||||
/*
|
||||
* When Magento\Framework\GraphQl\Config\Data is loaded from area outside of graphql, and its cache doesn't
|
||||
* currently exist, then it will load incorrect data and save it in its cache, which will then be used by
|
||||
* Magento\Framework\GraphQl\Config\Data when it actually is in the graphql area.
|
||||
* See AC-10465 for more details on this bug.
|
||||
*/
|
||||
$this->markTestSkipped('Fix this in AC-10465');
|
||||
$this->testAttributesChangeCleansGraphQlConfigCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Magento\CatalogGraphQl\Model\Config\AttributeReader has mutable state in
|
||||
* Magento\CatalogGraphQl\Model\Resolver\Products\Attributes\Collection $collection, so we must reset it.
|
||||
*
|
||||
* @param $objectManager
|
||||
* @return void
|
||||
*/
|
||||
private function resetStateProductsAttributesCollection($objectManager) : void
|
||||
{
|
||||
/** @var ProductsAttributesCollection $productsAttributesCollection */
|
||||
$productsAttributesCollection = $objectManager->get(ProductsAttributesCollection::class);
|
||||
$productsAttributesCollection->_resetState();
|
||||
}
|
||||
}
|
||||
+20
-3
@@ -102,7 +102,7 @@ class ConfigurableProductPriceTest extends TestCase
|
||||
{
|
||||
$this->executeInStoreContext->execute('fixture_second_store', [$this, 'assertPrice'], 'configurable', 10.00);
|
||||
$this->resetPageLayout();
|
||||
$this->assertPrice('configurable', 150.00);
|
||||
$this->assertAmount('configurable', 150.00);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,7 +112,7 @@ class ConfigurableProductPriceTest extends TestCase
|
||||
*/
|
||||
public function testConfigurablePriceWithDisabledFirstChild(): void
|
||||
{
|
||||
$this->assertPrice('configurable', 20.00);
|
||||
$this->assertAmount('configurable', 20.00);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,7 +122,7 @@ class ConfigurableProductPriceTest extends TestCase
|
||||
*/
|
||||
public function testConfigurablePriceWithOutOfStockFirstChild(): void
|
||||
{
|
||||
$this->assertPrice('configurable', 20.00);
|
||||
$this->assertAmount('configurable', 20.00);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,4 +254,21 @@ class ConfigurableProductPriceTest extends TestCase
|
||||
{
|
||||
return $this->productRepository->get($sku, false, $this->storeManager->getStore()->getId(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that html contain expected final price amount.
|
||||
*
|
||||
* @param string $sku
|
||||
* @param float $expectedPrice
|
||||
* @return void
|
||||
*/
|
||||
public function assertAmount(string $sku, float $expectedPrice): void
|
||||
{
|
||||
$priceBlockHtml = $this->processPriceView($sku);
|
||||
$regexp = '/<span\s+class="price">\$%.2f<\/span>/';
|
||||
$this->assertMatchesRegularExpression(
|
||||
sprintf($regexp, $expectedPrice),
|
||||
$priceBlockHtml
|
||||
);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -126,7 +126,7 @@ class ConfigurableViewOnCategoryPageTest extends TestCase
|
||||
__('As low as') . ' $10.00'
|
||||
);
|
||||
$this->resetPageLayout();
|
||||
$this->assertProductPrice('configurable', __('As low as') . ' $150.00');
|
||||
$this->assertProductPrice('configurable', '$150.00');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+16
-6
@@ -11,9 +11,9 @@ use Magento\Framework\App\Utility\Classes;
|
||||
use Magento\Framework\Exception\RuntimeException;
|
||||
use Magento\Framework\ObjectManager\FactoryInterface as ObjectManagerFactoryInterface;
|
||||
use Magento\Framework\ObjectManagerInterface;
|
||||
use Magento\GraphQl\App\State\Collector;
|
||||
use Magento\GraphQl\App\State\Comparator;
|
||||
use Magento\GraphQl\App\State\CompareType;
|
||||
use Magento\Framework\TestFramework\ApplicationStateComparator\Collector;
|
||||
use Magento\Framework\TestFramework\ApplicationStateComparator\Comparator;
|
||||
use Magento\Framework\TestFramework\ApplicationStateComparator\CompareType;
|
||||
|
||||
/**
|
||||
* Test that verifies that resetState method for classes cause the state to be the same as it was initially constructed
|
||||
@@ -167,9 +167,15 @@ class ResetAfterRequestTest extends \PHPUnit\Framework\TestCase
|
||||
}
|
||||
try {
|
||||
/** @var ResetAfterRequestInterface $object */
|
||||
$beforeProperties = $this->collector->getPropertiesFromObject($object, CompareType::CompareBetweenRequests);
|
||||
$beforeProperties = $this->collector->getPropertiesFromObject(
|
||||
$object,
|
||||
CompareType::COMPARE_BETWEEN_REQUESTS
|
||||
);
|
||||
$object->_resetState();
|
||||
$afterProperties = $this->collector->getPropertiesFromObject($object, CompareType::CompareBetweenRequests);
|
||||
$afterProperties = $this->collector->getPropertiesFromObject(
|
||||
$object,
|
||||
CompareType::COMPARE_BETWEEN_REQUESTS
|
||||
);
|
||||
$differences = [];
|
||||
foreach ($afterProperties as $propertyName => $propertyValue) {
|
||||
if ($propertyValue instanceof ObjectManagerInterface) {
|
||||
@@ -193,7 +199,11 @@ class ResetAfterRequestTest extends \PHPUnit\Framework\TestCase
|
||||
// TODO: Can we convert _regionModels to member variable,
|
||||
// or move to a dependency injected service class instead?
|
||||
}
|
||||
$result = $this->comparator->checkValues($beforeProperties[$propertyName] ?? null, $propertyValue, 3);
|
||||
$result = $this->comparator->checkValues(
|
||||
$beforeProperties[$propertyName] ?? null,
|
||||
$propertyValue,
|
||||
3
|
||||
);
|
||||
if ($result) {
|
||||
$differences[$propertyName] = $result;
|
||||
}
|
||||
|
||||
+761
@@ -0,0 +1,761 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App;
|
||||
|
||||
use Magento\Catalog\Api\ProductRepositoryInterface;
|
||||
use Magento\GraphQl\App\State\GraphQlStateDiff;
|
||||
|
||||
/**
|
||||
* Tests the dispatch method in the GraphQl Controller class using a simple product query
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
* @magentoDbIsolation disabled
|
||||
* @magentoAppIsolation enabled
|
||||
* @magentoAppArea graphql
|
||||
*/
|
||||
class GraphQlCheckoutMutationsStateTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var GraphQlStateDiff|null
|
||||
*/
|
||||
private ?GraphQlStateDiff $graphQlStateDiff = null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->graphQlStateDiff = new GraphQlStateDiff();
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$this->graphQlStateDiff->tearDown();
|
||||
$this->graphQlStateDiff = null;
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateEmptyCart() : void
|
||||
{
|
||||
$this->graphQlStateDiff->testState(
|
||||
$this->getEmptyCart(),
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
'createEmptyCart',
|
||||
'"data":{"createEmptyCart":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
|
||||
* @return void
|
||||
*/
|
||||
public function testAddSimpleProductToCart()
|
||||
{
|
||||
$this->markTestSkipped('Fixing in ACPT-1552');
|
||||
$cartId = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$query = $this->getAddProductToCartQuery();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['cartId' => $cartId, 'qty' => 1, 'sku' => 'simple_product'],
|
||||
[],
|
||||
[],
|
||||
'addSimpleProductsToCart',
|
||||
'"data":{"addSimpleProductsToCart":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
|
||||
* @magentoDataFixture Magento/SalesRule/_files/coupon_code_with_wildcard.php
|
||||
* @magentoDataFixture Magento/SalesRule/_files/coupon_cart_fixed_discount.php
|
||||
* @return void
|
||||
*/
|
||||
public function testAddCouponToCart()
|
||||
{
|
||||
$cartId = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$query = $this->getAddCouponToCartQuery();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['cartId' => $cartId, 'couponCode' => '2?ds5!2d'],
|
||||
['cartId' => $cartId, 'couponCode' => 'CART_FIXED_DISCOUNT_15'],
|
||||
[],
|
||||
'applyCouponToCart',
|
||||
'"data":{"applyCouponToCart":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/GraphQl/Catalog/_files/virtual_product.php
|
||||
* @return void
|
||||
*/
|
||||
public function testAddVirtualProductToCart()
|
||||
{
|
||||
$this->markTestSkipped('Fixing in ACPT-1552');
|
||||
$cartId = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$query = $this->getAddVirtualProductToCartQuery();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['cartId' => $cartId, 'quantity' => 1, 'sku' => 'virtual_product'],
|
||||
[],
|
||||
[],
|
||||
'addVirtualProductsToCart',
|
||||
'"data":{"addVirtualProductsToCart":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/Bundle/_files/product.php
|
||||
* @return void
|
||||
*/
|
||||
public function testAddBundleProductToCart()
|
||||
{
|
||||
$this->markTestSkipped('Fixing in ACPT-1552');
|
||||
$cartId = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$query = $this->getAddBundleProductToCartQuery($cartId, 'bundle-product');
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
'addBundleProductsToCart',
|
||||
'"data":{"addBundleProductsToCart":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
|
||||
* @return void
|
||||
*/
|
||||
public function testAddConfigurableProductToCart(): void
|
||||
{
|
||||
$this->markTestSkipped('Fixing in ACPT-1552');
|
||||
$cartId = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$query = $this->getAddConfigurableProductToCartQuery();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['cartId' => $cartId, 'quantity' => 2, 'parentSku' => 'configurable', 'childSku' => 'simple_20'],
|
||||
[],
|
||||
[],
|
||||
'addConfigurableProductsToCart',
|
||||
'"data":{"addConfigurableProductsToCart":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links.php
|
||||
* @return void
|
||||
*/
|
||||
public function testAddDownloadableProductToCart(): void
|
||||
{
|
||||
$this->markTestSkipped('Fixing in ACPT-1552');
|
||||
$cartId = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$sku = 'downloadable-product-with-purchased-separately-links';
|
||||
$links = $this->getProductsLinks($sku);
|
||||
$linkId = key($links);
|
||||
$query = $this->getAddDownloadableProductToCartQuery();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['cartId' => $cartId, 'qty' => 1, 'sku' => $sku, 'linkId' => $linkId],
|
||||
[],
|
||||
[],
|
||||
'addDownloadableProductsToCart',
|
||||
'"data":{"addDownloadableProductsToCart":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
|
||||
* @return void
|
||||
*/
|
||||
public function testSetShippingAddressOnCart(): void
|
||||
{
|
||||
$this->markTestSkipped('Fix this later');
|
||||
$cartId = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$query = $this->getShippingAddressQuery();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['cartId' => $cartId],
|
||||
[],
|
||||
[],
|
||||
'setShippingAddressesOnCart',
|
||||
'"data":{"setShippingAddressesOnCart":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php
|
||||
* @return void
|
||||
*/
|
||||
public function testSetBillingAddressOnCart(): void
|
||||
{
|
||||
$cartId = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$query = $this->getBillingAddressQuery();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['cartId' => $cartId],
|
||||
[],
|
||||
[],
|
||||
'setBillingAddressOnCart',
|
||||
'"data":{"setBillingAddressOnCart":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php
|
||||
* @return void
|
||||
*/
|
||||
public function testSetShippingMethodsOnCart(): void
|
||||
{
|
||||
$cartId = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$query = $this->getShippingMethodsQuery();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['cartId' => $cartId, 'shippingMethod' => 'flatrate'],
|
||||
[],
|
||||
[],
|
||||
'setShippingMethodsOnCart',
|
||||
'"data":{"setShippingMethodsOnCart":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php
|
||||
*/
|
||||
public function testSetPaymentMethodOnCart(): void
|
||||
{
|
||||
$cartId = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$query = $this->getPaymentMethodQuery();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['cartId' => $cartId],
|
||||
[],
|
||||
[],
|
||||
'setPaymentMethodOnCart',
|
||||
'"data":{"setPaymentMethodOnCart":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_checkmo_payment_method.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/set_guest_email.php
|
||||
*/
|
||||
public function testPlaceOrder(): void
|
||||
{
|
||||
$cartId = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$query = $this->getPlaceOrderQuery();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['cartId' => $cartId],
|
||||
[],
|
||||
[],
|
||||
'placeOrder',
|
||||
'"data":{"placeOrder":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
private function getBillingAddressQuery(): string
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($cartId: String!) {
|
||||
setBillingAddressOnCart(
|
||||
input: {
|
||||
cart_id: $cartId
|
||||
billing_address: {
|
||||
address: {
|
||||
firstname: "John"
|
||||
lastname: "Doe"
|
||||
street: ["123 Main Street"]
|
||||
city: "New York"
|
||||
region: "NY"
|
||||
postcode: "10001"
|
||||
country_code: "US"
|
||||
telephone: "555-555-5555"
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
cart {
|
||||
id
|
||||
billing_address {
|
||||
firstname
|
||||
lastname
|
||||
street
|
||||
city
|
||||
region {
|
||||
code
|
||||
label
|
||||
}
|
||||
postcode
|
||||
country {
|
||||
code
|
||||
label
|
||||
}
|
||||
telephone
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
private function getShippingAddressQuery(): string
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($cartId: String!) {
|
||||
setShippingAddressesOnCart(
|
||||
input: {
|
||||
cart_id: $cartId
|
||||
shipping_addresses: [
|
||||
{
|
||||
address: {
|
||||
firstname: "John"
|
||||
lastname: "Doe"
|
||||
street: ["123 Main Street"]
|
||||
city: "New York"
|
||||
region: "NY"
|
||||
postcode: "10001"
|
||||
country_code: "US"
|
||||
telephone: "555-555-5555"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
) {
|
||||
cart {
|
||||
id
|
||||
shipping_addresses {
|
||||
firstname
|
||||
lastname
|
||||
street
|
||||
city
|
||||
region {
|
||||
code
|
||||
label
|
||||
}
|
||||
postcode
|
||||
country {
|
||||
code
|
||||
label
|
||||
}
|
||||
telephone
|
||||
available_shipping_methods {
|
||||
carrier_code
|
||||
method_code
|
||||
amount {
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
/**
|
||||
* Function returns array of all product's links
|
||||
*
|
||||
* @param string $sku
|
||||
* @return array
|
||||
*/
|
||||
private function getProductsLinks(string $sku) : array
|
||||
{
|
||||
$result = [];
|
||||
$productRepository = $this->graphQlStateDiff->getTestObjectManager()
|
||||
->get(ProductRepositoryInterface::class);
|
||||
$product = $productRepository->get($sku, false, null, true);
|
||||
|
||||
foreach ($product->getDownloadableLinks() as $linkObject) {
|
||||
$result[$linkObject->getLinkId()] = [
|
||||
'title' => $linkObject->getTitle(),
|
||||
'link_type' => null, //deprecated field
|
||||
'price' => $linkObject->getPrice(),
|
||||
];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function getAddDownloadableProductToCartQuery(): string
|
||||
{
|
||||
return <<<'MUTATION'
|
||||
mutation($cartId: String!, $qty: Float!, $sku: String!, $linkId: Int!) {
|
||||
addDownloadableProductsToCart(
|
||||
input: {
|
||||
cart_id: $cartId,
|
||||
cart_items: [
|
||||
{
|
||||
data: {
|
||||
quantity: $qty,
|
||||
sku: $sku
|
||||
},
|
||||
downloadable_product_links: [
|
||||
{
|
||||
link_id: $linkId
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
) {
|
||||
cart {
|
||||
items {
|
||||
quantity
|
||||
... on DownloadableCartItem {
|
||||
links {
|
||||
title
|
||||
link_type
|
||||
price
|
||||
}
|
||||
samples {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MUTATION;
|
||||
}
|
||||
|
||||
private function getAddConfigurableProductToCartQuery(): string
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($cartId: String!, $quantity: Float!, $parentSku: String!, $childSku: String!) {
|
||||
addConfigurableProductsToCart(
|
||||
input:{
|
||||
cart_id: $cartId
|
||||
cart_items:{
|
||||
parent_sku: $parentSku
|
||||
data:{
|
||||
sku: $childSku
|
||||
quantity:$quantity
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
cart {
|
||||
id
|
||||
items {
|
||||
id
|
||||
quantity
|
||||
product {
|
||||
sku
|
||||
}
|
||||
... on ConfigurableCartItem {
|
||||
configurable_options {
|
||||
id
|
||||
option_label
|
||||
value_id
|
||||
value_label
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
private function getAddBundleProductToCartQuery(string $cartId, string $sku)
|
||||
{
|
||||
$productRepository = $this->graphQlStateDiff->getTestObjectManager()->get(ProductRepositoryInterface::class);
|
||||
$product = $productRepository->get($sku);
|
||||
/** @var $typeInstance \Magento\Bundle\Model\Product\Type */
|
||||
$typeInstance = $product->getTypeInstance();
|
||||
$typeInstance->setStoreFilter($product->getStoreId(), $product);
|
||||
/** @var $option \Magento\Bundle\Model\Option */
|
||||
$option = $typeInstance->getOptionsCollection($product)->getFirstItem();
|
||||
/** @var \Magento\Catalog\Model\Product $selection */
|
||||
$selection = $typeInstance->getSelectionsCollection([$option->getId()], $product)->getFirstItem();
|
||||
$optionId = $option->getId();
|
||||
$selectionId = $selection->getSelectionId();
|
||||
|
||||
return <<<QUERY
|
||||
mutation {
|
||||
addBundleProductsToCart(input:{
|
||||
cart_id:"{$cartId}"
|
||||
cart_items:[
|
||||
{
|
||||
data:{
|
||||
sku:"{$sku}"
|
||||
quantity:1
|
||||
}
|
||||
bundle_options:[
|
||||
{
|
||||
id:{$optionId}
|
||||
quantity:1
|
||||
value:[
|
||||
"{$selectionId}"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}) {
|
||||
cart {
|
||||
items {
|
||||
id
|
||||
uid
|
||||
quantity
|
||||
product {
|
||||
sku
|
||||
}
|
||||
... on BundleCartItem {
|
||||
bundle_options {
|
||||
id
|
||||
uid
|
||||
label
|
||||
type
|
||||
values {
|
||||
id
|
||||
uid
|
||||
label
|
||||
price
|
||||
quantity
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getAddProductToCartQuery(): string
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($cartId: String!, $qty: Float!, $sku: String!) {
|
||||
addSimpleProductsToCart(
|
||||
input: {
|
||||
cart_id: $cartId
|
||||
cart_items: [
|
||||
{
|
||||
data: {
|
||||
quantity: $qty
|
||||
sku: $sku
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
) {
|
||||
cart {
|
||||
items {
|
||||
quantity
|
||||
product {
|
||||
sku
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getAddVirtualProductToCartQuery(): string
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($cartId: String!, $quantity: Float!, $sku: String!) {
|
||||
addVirtualProductsToCart(
|
||||
input: {
|
||||
cart_id: $cartId
|
||||
cart_items: [
|
||||
{
|
||||
data: {
|
||||
quantity: $quantity
|
||||
sku: $sku
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
) {
|
||||
cart {
|
||||
id
|
||||
items {
|
||||
quantity
|
||||
product {
|
||||
sku
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getEmptyCart(): string
|
||||
{
|
||||
return <<<QUERY
|
||||
mutation {
|
||||
createEmptyCart
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getShippingMethodsQuery()
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($cartId: String!, $shippingMethod: String!) {
|
||||
setShippingMethodsOnCart(
|
||||
input: {
|
||||
cart_id: $cartId
|
||||
shipping_methods: [
|
||||
{
|
||||
carrier_code: $shippingMethod
|
||||
method_code: $shippingMethod
|
||||
}
|
||||
]
|
||||
}
|
||||
) {
|
||||
cart {
|
||||
id
|
||||
shipping_addresses {
|
||||
selected_shipping_method {
|
||||
carrier_code
|
||||
method_code
|
||||
carrier_title
|
||||
method_title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getPaymentMethodQuery()
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($cartId: String!) {
|
||||
setPaymentMethodOnCart(
|
||||
input: {
|
||||
cart_id: $cartId
|
||||
payment_method: {
|
||||
code: "checkmo"
|
||||
}
|
||||
}
|
||||
) {
|
||||
cart {
|
||||
id
|
||||
selected_payment_method {
|
||||
code
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getPlaceOrderQuery(): string
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($cartId: String!) {
|
||||
placeOrder(
|
||||
input: {
|
||||
cart_id: $cartId
|
||||
}
|
||||
) {
|
||||
order {
|
||||
order_number
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getAddCouponToCartQuery(): string
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($cartId: String!, $couponCode: String!) {
|
||||
applyCouponToCart(
|
||||
input: {
|
||||
cart_id: $cartId
|
||||
coupon_code: $couponCode
|
||||
}
|
||||
) {
|
||||
cart {
|
||||
id
|
||||
applied_coupons {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,505 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App;
|
||||
|
||||
use Magento\Customer\Api\CustomerRepositoryInterface;
|
||||
use Magento\Framework\Exception\NoSuchEntityException;
|
||||
use Magento\Framework\Registry;
|
||||
use Magento\GraphQl\App\State\GraphQlStateDiff;
|
||||
|
||||
/**
|
||||
* Tests the dispatch method in the GraphQl Controller class using a simple product query
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
* @magentoDbIsolation disabled
|
||||
* @magentoAppIsolation enabled
|
||||
* @magentoAppArea graphql
|
||||
*/
|
||||
class GraphQlCustomerMutationsTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var GraphQlStateDiff|null
|
||||
*/
|
||||
private ?GraphQlStateDiff $graphQlStateDiff = null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->graphQlStateDiff = new GraphQlStateDiff();
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$this->graphQlStateDiff->tearDown();
|
||||
$this->graphQlStateDiff = null;
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/Customer/_files/customer.php
|
||||
* @magentoDataFixture Magento/Customer/_files/customer_address.php
|
||||
* @dataProvider customerDataProvider
|
||||
* @return void
|
||||
*/
|
||||
public function testCustomerState(
|
||||
string $query,
|
||||
array $variables,
|
||||
array $variables2,
|
||||
array $authInfo,
|
||||
string $operationName,
|
||||
string $expected,
|
||||
) : void {
|
||||
$this->markTestSkipped('Fix this later');
|
||||
if ($operationName === 'createCustomer') {
|
||||
$emails = [$variables['email'], $variables2['email']];
|
||||
$this->clearCustomerBeforeTest($emails);
|
||||
}
|
||||
$this->graphQlStateDiff->
|
||||
testState($query, $variables, $variables2, $authInfo, $operationName, $expected, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $emails
|
||||
* @return void
|
||||
*/
|
||||
private function clearCustomerBeforeTest(array $emails): void
|
||||
{
|
||||
$customerRepository = $this->graphQlStateDiff->getTestObjectManager()
|
||||
->get(CustomerRepositoryInterface::class);
|
||||
$registry = $this->graphQlStateDiff->getTestObjectManager()->get(Registry::class);
|
||||
$registry->register('isSecureArea', true);
|
||||
foreach ($emails as $email) {
|
||||
try {
|
||||
$customer = $customerRepository->get($email);
|
||||
$customerRepository->delete($customer);
|
||||
} catch (NoSuchEntityException $e) {
|
||||
// Customer does not exist
|
||||
}
|
||||
}
|
||||
$registry->unregister('isSecureArea', false);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @magentoDataFixture Magento/Checkout/_files/quote_with_virtual_product_saved.php
|
||||
* @magentoDataFixture Magento/Customer/_files/customer.php
|
||||
* @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
|
||||
*/
|
||||
public function testMergeCarts(): void
|
||||
{
|
||||
$cartId1 = $this->graphQlStateDiff->getCartIdHash('test_order_with_virtual_product_without_address');
|
||||
$cartId2 = $this->graphQlStateDiff->getCartIdHash('test_quote');
|
||||
$query = $this->getCartMergeMutation();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['cartId1' => $cartId1, 'cartId2' => $cartId2],
|
||||
[],
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
'mergeCarts',
|
||||
'"data":{"mergeCarts":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/Customer/_files/customer.php
|
||||
* @return void
|
||||
*/
|
||||
public function testRequestPasswordResetEmail(): void
|
||||
{
|
||||
$this->markTestSkipped('Fix this later');
|
||||
$query = $this->getRequestPasswordResetEmailMutation();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['email' => 'customer@example.com'],
|
||||
[],
|
||||
[],
|
||||
'requestPasswordResetEmail',
|
||||
'"data":{"requestPasswordResetEmail":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/Customer/_files/customer.php
|
||||
* @return void
|
||||
*/
|
||||
public function testResetPassword(): void
|
||||
{
|
||||
$this->markTestSkipped('Fix this later');
|
||||
$query = $this->getResetPasswordMutation();
|
||||
$email = 'customer@example.com';
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['email' => $email, 'newPassword' => 'new_password123', 'resetPasswordToken' =>
|
||||
$this->graphQlStateDiff->getResetPasswordToken($email)],
|
||||
[],
|
||||
[],
|
||||
'resetPassword',
|
||||
'"data":{"resetPassword":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/Customer/_files/customer.php
|
||||
* @return void
|
||||
*/
|
||||
public function testChangePassword(): void
|
||||
{
|
||||
$this->markTestSkipped('Fix this later');
|
||||
$query = $this->getChangePasswordMutation();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
['currentPassword' => 'password', 'newPassword' => 'new_password123'],
|
||||
['currentPassword' => 'new_password123', 'newPassword' => 'password_new123'],
|
||||
[['email'=>'customer@example.com', 'password' => 'password'],
|
||||
['email'=>'customer@example.com', 'password' => 'new_password123']],
|
||||
'changeCustomerPassword',
|
||||
'"data":{"changeCustomerPassword":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/Customer/_files/customer_without_addresses.php
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateCustomerAddress(): void
|
||||
{
|
||||
$query = $this->getCreateCustomerAddressMutation();
|
||||
$this->graphQlStateDiff->testState(
|
||||
$query,
|
||||
[],
|
||||
[],
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
'createCustomerAddress',
|
||||
'"data":{"createCustomerAddress":',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries, variables, operation names, and expected responses for test
|
||||
*
|
||||
* @return array[]
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function customerDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'Create Customer' => [
|
||||
<<<'QUERY'
|
||||
mutation($firstname: String!, $lastname: String!, $email: String!, $password: String!) {
|
||||
createCustomerV2(
|
||||
input: {
|
||||
firstname: $firstname,
|
||||
lastname: $lastname,
|
||||
email: $email,
|
||||
password: $password
|
||||
}
|
||||
) {
|
||||
customer {
|
||||
created_at
|
||||
prefix
|
||||
firstname
|
||||
middlename
|
||||
lastname
|
||||
suffix
|
||||
email
|
||||
default_billing
|
||||
default_shipping
|
||||
date_of_birth
|
||||
taxvat
|
||||
is_subscribed
|
||||
gender
|
||||
allow_remote_shopping_assistance
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
[
|
||||
'firstname' => 'John',
|
||||
'lastname' => 'Doe',
|
||||
'email' => 'email1@example.com',
|
||||
'password' => 'Password-1',
|
||||
],
|
||||
[
|
||||
'firstname' => 'John',
|
||||
'lastname' => 'Doe',
|
||||
'email' => 'email2@adobe.com',
|
||||
'password' => 'Password-2',
|
||||
],
|
||||
[],
|
||||
'createCustomer',
|
||||
'"email":"',
|
||||
],
|
||||
'Update Customer' => [
|
||||
<<<'QUERY'
|
||||
mutation($allow: Boolean!) {
|
||||
updateCustomerV2(
|
||||
input: {
|
||||
allow_remote_shopping_assistance: $allow
|
||||
}
|
||||
) {
|
||||
customer {
|
||||
allow_remote_shopping_assistance
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
['allow' => true],
|
||||
['allow' => false],
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
'updateCustomer',
|
||||
'allow_remote_shopping_assistance'
|
||||
],
|
||||
'Update Customer Address' => [
|
||||
<<<'QUERY'
|
||||
mutation($addressId: Int!, $city: String!) {
|
||||
updateCustomerAddress(id: $addressId, input: {
|
||||
region: {
|
||||
region: "Alberta"
|
||||
region_id: 66
|
||||
region_code: "AB"
|
||||
}
|
||||
country_code: CA
|
||||
street: ["Line 1 Street","Line 2"]
|
||||
company: "Company Name"
|
||||
telephone: "123456789"
|
||||
fax: "123123123"
|
||||
postcode: "7777"
|
||||
city: $city
|
||||
firstname: "Adam"
|
||||
lastname: "Phillis"
|
||||
middlename: "A"
|
||||
prefix: "Mr."
|
||||
suffix: "Jr."
|
||||
vat_id: "1"
|
||||
default_shipping: true
|
||||
default_billing: true
|
||||
}) {
|
||||
id
|
||||
customer_id
|
||||
region {
|
||||
region
|
||||
region_id
|
||||
region_code
|
||||
}
|
||||
country_code
|
||||
street
|
||||
company
|
||||
telephone
|
||||
fax
|
||||
postcode
|
||||
city
|
||||
firstname
|
||||
lastname
|
||||
middlename
|
||||
prefix
|
||||
suffix
|
||||
vat_id
|
||||
default_shipping
|
||||
default_billing
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
['addressId' => 1, 'city' => 'New York'],
|
||||
['addressId' => 1, 'city' => 'Austin'],
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
'updateCustomerAddress',
|
||||
'city'
|
||||
],
|
||||
'Update Customer Email' => [
|
||||
<<<'QUERY'
|
||||
mutation($email: String!, $password: String!) {
|
||||
updateCustomerEmail(
|
||||
email: $email
|
||||
password: $password
|
||||
) {
|
||||
customer {
|
||||
email
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
['email' => 'customer2@example.com', 'password' => 'password'],
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
[
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
['email' => 'customer2@example.com', 'password' => 'password'],
|
||||
],
|
||||
'updateCustomerEmail',
|
||||
'email',
|
||||
],
|
||||
'Generate Customer Token' => [
|
||||
<<<'QUERY'
|
||||
mutation($email: String!, $password: String!) {
|
||||
generateCustomerToken(email: $email, password: $password) {
|
||||
token
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
[],
|
||||
'generateCustomerToken',
|
||||
'token'
|
||||
],
|
||||
'Get Customer' => [
|
||||
<<<'QUERY'
|
||||
query {
|
||||
customer {
|
||||
created_at
|
||||
date_of_birth
|
||||
default_billing
|
||||
default_shipping
|
||||
date_of_birth
|
||||
email
|
||||
firstname
|
||||
gender
|
||||
id
|
||||
is_subscribed
|
||||
lastname
|
||||
middlename
|
||||
prefix
|
||||
suffix
|
||||
taxvat
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
[],
|
||||
[],
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
'getCustomer',
|
||||
'"data":{"customer":{"created_at"'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function getCartMergeMutation(): string
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($cartId1: String!, $cartId2: String!) {
|
||||
mergeCarts(
|
||||
source_cart_id: $cartId1
|
||||
destination_cart_id: $cartId2
|
||||
) {
|
||||
items {
|
||||
quantity
|
||||
product {
|
||||
sku
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
private function getRequestPasswordResetEmailMutation(): string
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($email: String!) {
|
||||
requestPasswordResetEmail(email: $email)
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
private function getResetPasswordMutation()
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($email: String!, $newPassword: String!, $resetPasswordToken: String!) {
|
||||
resetPassword(
|
||||
email: $email
|
||||
resetPasswordToken: $resetPasswordToken
|
||||
newPassword: $newPassword
|
||||
)
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
private function getChangePasswordMutation()
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation($currentPassword: String!, $newPassword: String!) {
|
||||
changeCustomerPassword(
|
||||
currentPassword: $currentPassword
|
||||
newPassword: $newPassword
|
||||
) {
|
||||
id
|
||||
email
|
||||
firstname
|
||||
lastname
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
|
||||
private function getCreateCustomerAddressMutation(): string
|
||||
{
|
||||
return <<<'QUERY'
|
||||
mutation {
|
||||
createCustomerAddress(
|
||||
input: {
|
||||
region: {
|
||||
region: "Alberta"
|
||||
region_id: 66
|
||||
region_code: "AB"
|
||||
}
|
||||
country_code: CA
|
||||
street: ["Line 1 Street","Line 2"]
|
||||
company: "Company Name"
|
||||
telephone: "123456789"
|
||||
fax: "123123123"
|
||||
postcode: "7777"
|
||||
city: "New York"
|
||||
firstname: "Adam"
|
||||
lastname: "Phillis"
|
||||
middlename: "A"
|
||||
prefix: "Mr."
|
||||
suffix: "Jr."
|
||||
vat_id: "1"
|
||||
default_shipping: true
|
||||
default_billing: true
|
||||
}
|
||||
) {
|
||||
id
|
||||
customer_id
|
||||
region {
|
||||
region
|
||||
region_id
|
||||
region_code
|
||||
}
|
||||
country_code
|
||||
street
|
||||
company
|
||||
telephone
|
||||
fax
|
||||
postcode
|
||||
city
|
||||
firstname
|
||||
lastname
|
||||
middlename
|
||||
prefix
|
||||
suffix
|
||||
vat_id
|
||||
default_shipping
|
||||
default_billing
|
||||
}
|
||||
}
|
||||
QUERY;
|
||||
}
|
||||
}
|
||||
@@ -7,17 +7,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App;
|
||||
|
||||
use Magento\Customer\Api\CustomerRepositoryInterface;
|
||||
use Magento\Framework\App\Http as HttpApp;
|
||||
use Magento\Framework\App\ObjectManager as AppObjectManager;
|
||||
use Magento\Framework\App\Request\HttpFactory as RequestFactory;
|
||||
use Magento\Framework\App\Response\Http as HttpResponse;
|
||||
use Magento\Framework\ObjectManagerInterface;
|
||||
use Magento\Framework\Registry;
|
||||
use Magento\GraphQl\App\State\Comparator;
|
||||
use Magento\GraphQl\App\State\ObjectManager;
|
||||
use Magento\Integration\Api\CustomerTokenServiceInterface;
|
||||
use Magento\TestFramework\Helper\Bootstrap;
|
||||
use Magento\GraphQl\App\State\GraphQlStateDiff;
|
||||
use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId;
|
||||
|
||||
/**
|
||||
* Tests the dispatch method in the GraphQl Controller class using a simple product query
|
||||
@@ -26,45 +17,25 @@ use Magento\TestFramework\Helper\Bootstrap;
|
||||
* @magentoDbIsolation disabled
|
||||
* @magentoAppIsolation enabled
|
||||
* @magentoAppArea graphql
|
||||
* @magentoDataFixture Magento/Catalog/_files/multiple_mixed_products.php
|
||||
* @magentoDataFixture Magento/Catalog/_files/categories.php
|
||||
*
|
||||
*/
|
||||
class GraphQlStateTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private const CONTENT_TYPE = 'application/json';
|
||||
/**
|
||||
* @var GetMaskedQuoteIdByReservedOrderId
|
||||
*/
|
||||
private $getMaskedQuoteIdByReservedOrderId;
|
||||
|
||||
/** @var ObjectManagerInterface */
|
||||
private ObjectManagerInterface $objectManagerBeforeTest;
|
||||
|
||||
/** @var ObjectManager */
|
||||
private ObjectManager $objectManagerForTest;
|
||||
|
||||
/** @var Comparator */
|
||||
private Comparator $comparator;
|
||||
|
||||
/** @var RequestFactory */
|
||||
private RequestFactory $requestFactory;
|
||||
|
||||
/** @var CustomerRepositoryInterface */
|
||||
private CustomerRepositoryInterface $customerRepository;
|
||||
|
||||
/** @var Registry */
|
||||
private $registry;
|
||||
/**
|
||||
* @var GraphQlStateDiff|null
|
||||
*/
|
||||
private ?GraphQlStateDiff $graphQlStateDiff;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->objectManagerBeforeTest = Bootstrap::getObjectManager();
|
||||
$this->objectManagerForTest = new ObjectManager($this->objectManagerBeforeTest);
|
||||
$this->objectManagerForTest->getFactory()->setObjectManager($this->objectManagerForTest);
|
||||
AppObjectManager::setInstance($this->objectManagerForTest);
|
||||
Bootstrap::setObjectManager($this->objectManagerForTest);
|
||||
$this->comparator = $this->objectManagerForTest->create(Comparator::class);
|
||||
$this->requestFactory = $this->objectManagerForTest->get(RequestFactory::class);
|
||||
$this->objectManagerForTest->resetStateSharedInstances();
|
||||
$this->graphQlStateDiff = new GraphQlStateDiff();
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
@@ -73,48 +44,13 @@ class GraphQlStateTest extends \PHPUnit\Framework\TestCase
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$this->objectManagerBeforeTest->getFactory()->setObjectManager($this->objectManagerBeforeTest);
|
||||
AppObjectManager::setInstance($this->objectManagerBeforeTest);
|
||||
Bootstrap::setObjectManager($this->objectManagerBeforeTest);
|
||||
$this->graphQlStateDiff->tearDown();
|
||||
$this->graphQlStateDiff = null;
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoDataFixture Magento/Customer/_files/customer.php
|
||||
* @magentoDataFixture Magento/Customer/_files/customer_address.php
|
||||
* @dataProvider customerDataProvider
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function testCustomerState(
|
||||
string $query,
|
||||
array $variables,
|
||||
array $variables2,
|
||||
array $authInfo,
|
||||
string $operationName,
|
||||
string $expected,
|
||||
) : void {
|
||||
if ($operationName === 'createCustomer') {
|
||||
$this->customerRepository = $this->objectManagerForTest->get(CustomerRepositoryInterface::class);
|
||||
$this->registry = $this->objectManagerForTest->get(Registry::class);
|
||||
$this->registry->register('isSecureArea', true);
|
||||
try {
|
||||
$customer = $this->customerRepository->get($variables['email']);
|
||||
$this->customerRepository->delete($customer);
|
||||
$customer2 = $this->customerRepository->get($variables2['email']);
|
||||
$this->customerRepository->delete($customer2);
|
||||
} catch (\Exception $e) {
|
||||
// Customer does not exist
|
||||
} finally {
|
||||
$this->registry->unregister('isSecureArea', false);
|
||||
}
|
||||
}
|
||||
$this->testState($query, $variables, $variables2, $authInfo, $operationName, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs various GraphQL queries and checks if state of shared objects in Object Manager have changed
|
||||
*
|
||||
* @dataProvider queryDataProvider
|
||||
* @param string $query
|
||||
* @param array $variables
|
||||
@@ -122,6 +58,9 @@ class GraphQlStateTest extends \PHPUnit\Framework\TestCase
|
||||
* @param array $authInfo
|
||||
* @param string $operationName
|
||||
* @param string $expected
|
||||
* @magentoDataFixture Magento/Store/_files/store.php
|
||||
* @magentoDataFixture Magento/Catalog/_files/multiple_mixed_products.php
|
||||
* @magentoDataFixture Magento/Catalog/_files/categories.php
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
@@ -133,94 +72,49 @@ class GraphQlStateTest extends \PHPUnit\Framework\TestCase
|
||||
string $operationName,
|
||||
string $expected,
|
||||
): void {
|
||||
if (array_key_exists(1, $authInfo)) {
|
||||
$authInfo1 = $authInfo[0];
|
||||
$authInfo2 = $authInfo[1];
|
||||
} else {
|
||||
$authInfo1 = $authInfo;
|
||||
$authInfo2 = $authInfo;
|
||||
}
|
||||
$jsonEncodedRequest = json_encode([
|
||||
'query' => $query,
|
||||
'variables' => $variables,
|
||||
'operationName' => $operationName
|
||||
]);
|
||||
$output1 = $this->request($jsonEncodedRequest, $operationName, $authInfo1, true);
|
||||
$this->assertStringContainsString($expected, $output1);
|
||||
if ($variables2) {
|
||||
$jsonEncodedRequest = json_encode([
|
||||
'query' => $query,
|
||||
'variables' => $variables2,
|
||||
'operationName' => $operationName
|
||||
]);
|
||||
}
|
||||
$output2 = $this->request($jsonEncodedRequest, $operationName, $authInfo2);
|
||||
$this->assertStringContainsString($expected, $output2);
|
||||
$this->graphQlStateDiff
|
||||
->testState($query, $variables, $variables2, $authInfo, $operationName, $expected, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoConfigFixture default_store catalog/seo/product_url_suffix test_product_suffix
|
||||
* @magentoConfigFixture default_store catalog/seo/category_url_suffix test_category_suffix
|
||||
* @magentoConfigFixture default_store catalog/seo/title_separator ___
|
||||
* @magentoConfigFixture default_store catalog/frontend/list_mode 2
|
||||
* @magentoConfigFixture default_store catalog/frontend/grid_per_page_values 16
|
||||
* @magentoConfigFixture default_store catalog/frontend/list_per_page_values 8
|
||||
* @magentoConfigFixture default_store catalog/frontend/grid_per_page 16
|
||||
* @magentoConfigFixture default_store catalog/frontend/list_per_page 8
|
||||
* @magentoConfigFixture default_store catalog/frontend/default_sort_by asc
|
||||
* @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php
|
||||
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php
|
||||
* @dataProvider cartQueryProvider
|
||||
* @param string $query
|
||||
* @param string $operationName
|
||||
* @param array $variables
|
||||
* @param array $variables2
|
||||
* @param array $authInfo
|
||||
* @param bool $firstRequest
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
* @param string $operationName
|
||||
* @param string $expected
|
||||
* @return void
|
||||
*/
|
||||
private function request(string $query, string $operationName, array $authInfo, bool $firstRequest = false): string
|
||||
{
|
||||
$this->objectManagerForTest->resetStateSharedInstances();
|
||||
$this->comparator->rememberObjectsStateBefore($firstRequest);
|
||||
$response = $this->doRequest($query, $authInfo);
|
||||
$this->objectManagerForTest->resetStateSharedInstances();
|
||||
$this->comparator->rememberObjectsStateAfter($firstRequest);
|
||||
$result = $this->comparator->compareBetweenRequests($operationName);
|
||||
$this->assertEmpty(
|
||||
$result,
|
||||
sprintf(
|
||||
'%d objects changed state during request. Details: %s',
|
||||
count($result),
|
||||
var_export($result, true)
|
||||
)
|
||||
);
|
||||
$result = $this->comparator->compareConstructedAgainstCurrent($operationName);
|
||||
$this->assertEmpty(
|
||||
$result,
|
||||
sprintf(
|
||||
'%d objects changed state since constructed. Details: %s',
|
||||
count($result),
|
||||
var_export($result, true)
|
||||
)
|
||||
);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the GraphQL request
|
||||
*
|
||||
* @param string $query
|
||||
* @return string
|
||||
*/
|
||||
private function doRequest(string $query, array $authInfo)
|
||||
{
|
||||
$request = $this->requestFactory->create();
|
||||
$request->setContent($query);
|
||||
$request->setMethod('POST');
|
||||
$request->setPathInfo('/graphql');
|
||||
$request->getHeaders()->addHeaders(['content_type' => self::CONTENT_TYPE]);
|
||||
if ($authInfo) {
|
||||
$email = $authInfo['email'];
|
||||
$password = $authInfo['password'];
|
||||
$customerToken = $this->objectManagerForTest->get(CustomerTokenServiceInterface::class)
|
||||
->createCustomerAccessToken($email, $password);
|
||||
$request->getHeaders()->addHeaders(['Authorization' => 'Bearer ' . $customerToken]);
|
||||
public function testCartState(
|
||||
string $query,
|
||||
array $variables,
|
||||
array $variables2,
|
||||
array $authInfo,
|
||||
string $operationName,
|
||||
string $expected
|
||||
): void {
|
||||
if ($operationName == 'getCart') {
|
||||
$this->getMaskedQuoteIdByReservedOrderId =
|
||||
$this->graphQlStateDiff->getTestObjectManager()->get(GetMaskedQuoteIdByReservedOrderId::class);
|
||||
$variables['id'] = $this->getMaskedQuoteIdByReservedOrderId->execute($variables['id']);
|
||||
}
|
||||
$unusedResponse = $this->objectManagerForTest->create(HttpResponse::class);
|
||||
$httpApp = $this->objectManagerForTest->create(
|
||||
HttpApp::class,
|
||||
['request' => $request, 'response' => $unusedResponse]
|
||||
);
|
||||
$actualResponse = $httpApp->launch();
|
||||
return $actualResponse->getContent();
|
||||
$this->graphQlStateDiff
|
||||
->testState($query, $variables, $variables2, $authInfo, $operationName, $expected, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,8 +122,9 @@ class GraphQlStateTest extends \PHPUnit\Framework\TestCase
|
||||
*
|
||||
* @return array[]
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
|
||||
*/
|
||||
public function queryDataProvider(): array
|
||||
private function queryDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'Get Navigation Menu by category_id' => [
|
||||
@@ -449,176 +344,215 @@ class GraphQlStateTest extends \PHPUnit\Framework\TestCase
|
||||
'resolveUrl',
|
||||
'"type":"CMS_PAGE","id":1'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries, variables, operation names, and expected responses for test
|
||||
*
|
||||
* @return array[]
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function customerDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'Create Customer' => [
|
||||
'Get available Stores' => [
|
||||
<<<'QUERY'
|
||||
mutation($firstname: String!, $lastname: String!, $email: String!, $password: String!) {
|
||||
createCustomerV2(
|
||||
input: {
|
||||
firstname: $firstname,
|
||||
lastname: $lastname,
|
||||
email: $email,
|
||||
password: $password
|
||||
}
|
||||
) {
|
||||
customer {
|
||||
created_at
|
||||
prefix
|
||||
firstname
|
||||
middlename
|
||||
lastname
|
||||
suffix
|
||||
email
|
||||
default_billing
|
||||
default_shipping
|
||||
date_of_birth
|
||||
taxvat
|
||||
is_subscribed
|
||||
gender
|
||||
allow_remote_shopping_assistance
|
||||
query availableStores($currentGroup: Boolean!) {
|
||||
availableStores(useCurrentGroup:$currentGroup) {
|
||||
id,
|
||||
code,
|
||||
store_code,
|
||||
store_name,
|
||||
store_sort_order,
|
||||
is_default_store,
|
||||
store_group_code,
|
||||
store_group_name,
|
||||
is_default_store_group,
|
||||
website_id,
|
||||
website_code,
|
||||
website_name,
|
||||
locale,
|
||||
base_currency_code,
|
||||
default_display_currency_code,
|
||||
timezone,
|
||||
weight_unit,
|
||||
base_url,
|
||||
base_link_url,
|
||||
base_media_url,
|
||||
secure_base_url,
|
||||
secure_base_link_url,
|
||||
secure_base_static_url,
|
||||
secure_base_media_url,
|
||||
store_name
|
||||
use_store_in_url
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
[
|
||||
'firstname' => 'John',
|
||||
'lastname' => 'Doe',
|
||||
'email' => 'email1@example.com',
|
||||
'password' => 'Password-1',
|
||||
],
|
||||
[
|
||||
'firstname' => 'John',
|
||||
'lastname' => 'Doe',
|
||||
'email' => 'email2@adobe.com',
|
||||
'password' => 'Password-2',
|
||||
],
|
||||
[],
|
||||
'createCustomer',
|
||||
'"email":"',
|
||||
],
|
||||
'Update Customer' => [
|
||||
<<<'QUERY'
|
||||
mutation($allow: Boolean!) {
|
||||
updateCustomerV2(
|
||||
input: {
|
||||
allow_remote_shopping_assistance: $allow
|
||||
}
|
||||
) {
|
||||
customer {
|
||||
allow_remote_shopping_assistance
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
['allow' => true],
|
||||
['allow' => false],
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
'updateCustomer',
|
||||
'allow_remote_shopping_assistance'
|
||||
],
|
||||
'Update Customer Address' => [
|
||||
<<<'QUERY'
|
||||
mutation($addressId: Int!, $city: String!) {
|
||||
updateCustomerAddress(id: $addressId, input: {
|
||||
region: {
|
||||
region: "Alberta"
|
||||
region_id: 66
|
||||
region_code: "AB"
|
||||
}
|
||||
country_code: CA
|
||||
street: ["Line 1 Street","Line 2"]
|
||||
company: "Company Name"
|
||||
telephone: "123456789"
|
||||
fax: "123123123"
|
||||
postcode: "7777"
|
||||
city: $city
|
||||
firstname: "Adam"
|
||||
lastname: "Phillis"
|
||||
middlename: "A"
|
||||
prefix: "Mr."
|
||||
suffix: "Jr."
|
||||
vat_id: "1"
|
||||
default_shipping: true
|
||||
default_billing: true
|
||||
}) {
|
||||
id
|
||||
customer_id
|
||||
region {
|
||||
region
|
||||
region_id
|
||||
region_code
|
||||
}
|
||||
country_code
|
||||
street
|
||||
company
|
||||
telephone
|
||||
fax
|
||||
postcode
|
||||
city
|
||||
firstname
|
||||
lastname
|
||||
middlename
|
||||
prefix
|
||||
suffix
|
||||
vat_id
|
||||
default_shipping
|
||||
default_billing
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
['addressId' => 1, 'city' => 'New York'],
|
||||
['addressId' => 1, 'city' => 'Austin'],
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
'updateCustomerAddress',
|
||||
'city'
|
||||
['currentGroup' => true],
|
||||
[],
|
||||
[],
|
||||
'availableStores',
|
||||
'"store_code":"default"'
|
||||
],
|
||||
'Update Customer Email' => [
|
||||
'Get store config' => [
|
||||
<<<'QUERY'
|
||||
mutation($email: String!, $password: String!) {
|
||||
updateCustomerEmail(
|
||||
email: $email
|
||||
password: $password
|
||||
) {
|
||||
customer {
|
||||
email
|
||||
query {
|
||||
storeConfig {
|
||||
product_url_suffix,
|
||||
category_url_suffix,
|
||||
title_separator,
|
||||
list_mode,
|
||||
grid_per_page_values,
|
||||
list_per_page_values,
|
||||
grid_per_page,
|
||||
list_per_page,
|
||||
catalog_default_sort_by,
|
||||
root_category_id
|
||||
root_category_uid
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
'storeConfig',
|
||||
'"storeConfig":{"product_url_suffix":".html"'
|
||||
],
|
||||
'Get Categories by name' => [
|
||||
<<<'QUERY'
|
||||
query categories($name: String!) {
|
||||
categories(filters: {name: {match: $name}}
|
||||
pageSize: 3
|
||||
currentPage: 3
|
||||
) {
|
||||
total_count
|
||||
page_info {
|
||||
current_page
|
||||
page_size
|
||||
total_pages
|
||||
|
||||
}
|
||||
items {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
['name' => 'Category'],
|
||||
[],
|
||||
[],
|
||||
'categories',
|
||||
'"data":{"categories"'
|
||||
],
|
||||
'Get Products by name' => [
|
||||
<<<'QUERY'
|
||||
query products($name: String!) {
|
||||
products(
|
||||
search: $name
|
||||
filter: {}
|
||||
pageSize: 1000
|
||||
currentPage: 1
|
||||
sort: {name: ASC}
|
||||
) {
|
||||
|
||||
items {
|
||||
name
|
||||
image
|
||||
{
|
||||
url
|
||||
}
|
||||
attribute_set_id
|
||||
canonical_url
|
||||
color
|
||||
country_of_manufacture
|
||||
created_at
|
||||
gift_message_available
|
||||
id
|
||||
manufacturer
|
||||
meta_description
|
||||
meta_keyword
|
||||
meta_title
|
||||
new_from_date
|
||||
new_to_date
|
||||
only_x_left_in_stock
|
||||
options_container
|
||||
rating_summary
|
||||
review_count
|
||||
sku
|
||||
special_price
|
||||
special_to_date
|
||||
stock_status
|
||||
swatch_image
|
||||
uid
|
||||
updated_at
|
||||
url_key
|
||||
url_path
|
||||
url_suffix
|
||||
|
||||
}
|
||||
page_info {
|
||||
current_page
|
||||
page_size
|
||||
total_pages
|
||||
}
|
||||
sort_fields {
|
||||
default
|
||||
}
|
||||
suggestions {
|
||||
search
|
||||
}
|
||||
total_count
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
['email' => 'customer2@example.com', 'password' => 'password'],
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
[
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
['email' => 'customer2@example.com', 'password' => 'password'],
|
||||
],
|
||||
'updateCustomerEmail',
|
||||
'email',
|
||||
],
|
||||
'Generate Customer Token' => [
|
||||
<<<'QUERY'
|
||||
mutation($email: String!, $password: String!) {
|
||||
generateCustomerToken(email: $email, password: $password) {
|
||||
token
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
['email' => 'customer@example.com', 'password' => 'password'],
|
||||
['name' => 'Simple Product1'],
|
||||
[],
|
||||
'generateCustomerToken',
|
||||
'token'
|
||||
]
|
||||
[],
|
||||
'products',
|
||||
'"data":{"products":{"items":[{'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function cartQueryProvider(): array
|
||||
{
|
||||
return [
|
||||
'Get Cart' => [
|
||||
<<<'QUERY'
|
||||
query cart($id: String!) {
|
||||
cart(cart_id: $id) {
|
||||
applied_coupons {
|
||||
code
|
||||
}
|
||||
|
||||
available_payment_methods {
|
||||
code
|
||||
is_deferred
|
||||
title
|
||||
}
|
||||
billing_address {
|
||||
city
|
||||
company
|
||||
firstname
|
||||
lastname
|
||||
postcode
|
||||
street
|
||||
telephone
|
||||
uid
|
||||
vat_id
|
||||
}
|
||||
email
|
||||
id
|
||||
is_virtual
|
||||
items {
|
||||
id
|
||||
quantity
|
||||
uid
|
||||
}
|
||||
selected_payment_method {
|
||||
code
|
||||
purchase_order_number
|
||||
title
|
||||
}
|
||||
total_quantity
|
||||
}
|
||||
}
|
||||
QUERY,
|
||||
['id' => 'test_quote'],
|
||||
[],
|
||||
[],
|
||||
'getCart',
|
||||
'"cart":{"applied_coupons":null,"available_payment_methods":[{"code":"checkmo"'
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App\State;
|
||||
|
||||
/**
|
||||
* What type of comparison
|
||||
*
|
||||
* TODO: change this back into enum once magento-semvar is fixed
|
||||
*/
|
||||
class CompareType
|
||||
{
|
||||
public const CompareBetweenRequests = "CompareBetweenRequests";
|
||||
public const CompareConstructedAgainstCurrent = "CompareConstructedAgainstCurrent";
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App\State;
|
||||
|
||||
use Magento\Customer\Api\AccountManagementInterface;
|
||||
use Magento\Customer\Model\AccountManagement;
|
||||
use Magento\Customer\Model\CustomerRegistry;
|
||||
use Magento\Framework\App\Http as HttpApp;
|
||||
use Magento\Framework\App\ObjectManager as AppObjectManager;
|
||||
use Magento\Framework\App\RequestInterface;
|
||||
use Magento\Framework\App\Response\Http as HttpResponse;
|
||||
use Magento\Framework\Exception\LocalizedException;
|
||||
use Magento\Framework\Exception\NoSuchEntityException;
|
||||
use Magento\Framework\ObjectManagerInterface;
|
||||
use Magento\Framework\TestFramework\ApplicationStateComparator\Comparator;
|
||||
use Magento\Framework\TestFramework\ApplicationStateComparator\ObjectManager;
|
||||
use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId;
|
||||
use Magento\Integration\Api\CustomerTokenServiceInterface;
|
||||
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
|
||||
use Magento\TestFramework\Helper\Bootstrap;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Tests the dispatch method in the GraphQl Controller class using a simple product query
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class GraphQlStateDiff
|
||||
{
|
||||
private const CONTENT_TYPE = 'application/json';
|
||||
|
||||
/**
|
||||
* @var ObjectManagerInterface
|
||||
*
|
||||
* phpcs:disable Magento2.Commenting.ClassPropertyPHPDocFormatting
|
||||
*/
|
||||
private readonly ObjectManagerInterface $objectManagerBeforeTest;
|
||||
|
||||
/**
|
||||
* @var ObjectManager
|
||||
*
|
||||
* phpcs:disable Magento2.Commenting.ClassPropertyPHPDocFormatting
|
||||
*/
|
||||
private readonly ObjectManager $objectManagerForTest;
|
||||
|
||||
/**
|
||||
* @var Comparator
|
||||
*
|
||||
* phpcs:disable Magento2.Commenting.ClassPropertyPHPDocFormatting
|
||||
*/
|
||||
private readonly Comparator $comparator;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->objectManagerBeforeTest = Bootstrap::getObjectManager();
|
||||
$this->objectManagerForTest = new ObjectManager($this->objectManagerBeforeTest);
|
||||
$this->objectManagerForTest->getFactory()->setObjectManager($this->objectManagerForTest);
|
||||
AppObjectManager::setInstance($this->objectManagerForTest);
|
||||
Bootstrap::setObjectManager($this->objectManagerForTest);
|
||||
$this->comparator = $this->objectManagerForTest->create(Comparator::class);
|
||||
$this->objectManagerForTest->resetStateSharedInstances();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets test object manager
|
||||
*
|
||||
* @return ObjectManager
|
||||
*/
|
||||
public function getTestObjectManager()
|
||||
{
|
||||
return $this->objectManagerForTest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tear Down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function tearDown(): void
|
||||
{
|
||||
$this->objectManagerBeforeTest->getFactory()->setObjectManager($this->objectManagerBeforeTest);
|
||||
AppObjectManager::setInstance($this->objectManagerBeforeTest);
|
||||
Bootstrap::setObjectManager($this->objectManagerBeforeTest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests state
|
||||
*
|
||||
* @param string $query
|
||||
* @param array $variables
|
||||
* @param array $variables2
|
||||
* @param array $authInfo
|
||||
* @param string $operationName
|
||||
* @param string $expected
|
||||
* @param TestCase $test
|
||||
* @return void
|
||||
* @throws LocalizedException
|
||||
* @throws NoSuchEntityException
|
||||
* @throws \Magento\Framework\Exception\AuthenticationException
|
||||
* @throws \Magento\Framework\Exception\CouldNotDeleteException
|
||||
*/
|
||||
public function testState(
|
||||
string $query,
|
||||
array $variables,
|
||||
array $variables2,
|
||||
array $authInfo,
|
||||
string $operationName,
|
||||
string $expected,
|
||||
TestCase $test
|
||||
): void {
|
||||
if (array_key_exists(1, $authInfo)) {
|
||||
$authInfo1 = $authInfo[0];
|
||||
$authInfo2 = $authInfo[1];
|
||||
} else {
|
||||
$authInfo1 = $authInfo;
|
||||
$authInfo2 = $authInfo;
|
||||
}
|
||||
$jsonEncodedRequest = json_encode([
|
||||
'query' => $query,
|
||||
'variables' => $variables,
|
||||
'operationName' => $operationName
|
||||
]);
|
||||
$output1 = $this->request($jsonEncodedRequest, $operationName, $authInfo1, $test, true);
|
||||
$test->assertStringContainsString($expected, $output1);
|
||||
if ($operationName === 'placeOrder' || $operationName === 'mergeCarts') {
|
||||
foreach ($variables as $cartId) {
|
||||
$this->reactivateCart($cartId);
|
||||
}
|
||||
} elseif ($operationName==='applyCouponToCart') {
|
||||
$this->removeCouponFromCart($variables);
|
||||
} elseif ($operationName==='resetPassword') {
|
||||
$variables2['resetPasswordToken'] = $this->getResetPasswordToken($variables['email']);
|
||||
$variables2['email'] = $variables['email'];
|
||||
$variables2['newPassword'] = $variables['newPassword'];
|
||||
}
|
||||
|
||||
if ($variables2) {
|
||||
$jsonEncodedRequest = json_encode([
|
||||
'query' => $query,
|
||||
'variables' => $variables2,
|
||||
'operationName' => $operationName
|
||||
]);
|
||||
}
|
||||
$output2 = $this->request($jsonEncodedRequest, $operationName, $authInfo2, $test);
|
||||
$test->assertStringContainsString($expected, $output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes request
|
||||
*
|
||||
* @param string $query
|
||||
* @param string $operationName
|
||||
* @param array $authInfo
|
||||
* @param TestCase $test
|
||||
* @param bool $firstRequest
|
||||
* @return string
|
||||
* @throws LocalizedException
|
||||
* @throws \Magento\Framework\Exception\AuthenticationException
|
||||
*/
|
||||
private function request(
|
||||
string $query,
|
||||
string $operationName,
|
||||
array $authInfo,
|
||||
TestCase $test,
|
||||
bool $firstRequest = false
|
||||
): string {
|
||||
$this->objectManagerForTest->resetStateSharedInstances();
|
||||
$this->comparator->rememberObjectsStateBefore($firstRequest);
|
||||
$response = $this->doRequest($query, $authInfo);
|
||||
$this->objectManagerForTest->resetStateSharedInstances();
|
||||
$this->comparator->rememberObjectsStateAfter($firstRequest);
|
||||
$result = $this->comparator->compareBetweenRequests($operationName);
|
||||
$test->assertEmpty(
|
||||
$result,
|
||||
sprintf(
|
||||
'%d objects changed state during request. Details: %s',
|
||||
count($result),
|
||||
var_export($result, true)
|
||||
)
|
||||
);
|
||||
$result = $this->comparator->compareConstructedAgainstCurrent($operationName);
|
||||
$test->assertEmpty(
|
||||
$result,
|
||||
sprintf(
|
||||
'%d objects changed state since constructed. Details: %s',
|
||||
count($result),
|
||||
var_export($result, true)
|
||||
)
|
||||
);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the GraphQL request
|
||||
*
|
||||
* @param string $query
|
||||
* @param array $authInfo
|
||||
* @return mixed|string
|
||||
* @throws LocalizedException
|
||||
* @throws \Magento\Framework\Exception\AuthenticationException
|
||||
*/
|
||||
private function doRequest(string $query, array $authInfo)
|
||||
{
|
||||
$request = $this->objectManagerForTest->get(RequestInterface::class);
|
||||
$request->setContent($query);
|
||||
$request->setMethod('POST');
|
||||
$request->setPathInfo('/graphql');
|
||||
$request->getHeaders()->addHeaders(['content_type' => self::CONTENT_TYPE]);
|
||||
if ($authInfo) {
|
||||
$email = $authInfo['email'];
|
||||
$password = $authInfo['password'];
|
||||
$customerToken = $this->objectManagerForTest->get(CustomerTokenServiceInterface::class)
|
||||
->createCustomerAccessToken($email, $password);
|
||||
$request->getHeaders()->addHeaders(['Authorization' => 'Bearer ' . $customerToken]);
|
||||
}
|
||||
$unusedResponse = $this->objectManagerForTest->create(HttpResponse::class);
|
||||
$httpApp = $this->objectManagerForTest->create(
|
||||
HttpApp::class,
|
||||
['request' => $request, 'response' => $unusedResponse]
|
||||
);
|
||||
$actualResponse = $httpApp->launch();
|
||||
return $actualResponse->getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes coupon from cart
|
||||
*
|
||||
* @param array $variables
|
||||
* @return void
|
||||
* @throws NoSuchEntityException
|
||||
* @throws \Magento\Framework\Exception\CouldNotDeleteException
|
||||
*/
|
||||
private function removeCouponFromCart(array $variables)
|
||||
{
|
||||
$couponManagement = $this->objectManagerForTest->get(\Magento\Quote\Api\CouponManagementInterface::class);
|
||||
$cartId = $this->getCartId($variables['cartId']);
|
||||
$couponManagement->remove($cartId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reactivates cart
|
||||
*
|
||||
* @param string $cartId
|
||||
* @return void
|
||||
* @throws NoSuchEntityException
|
||||
*/
|
||||
private function reactivateCart(string $cartId)
|
||||
{
|
||||
$cartId = $this->getCartId($cartId);
|
||||
$cart = $this->objectManagerForTest->get(\Magento\Quote\Model\Quote::class);
|
||||
$cart->load($cartId);
|
||||
$cart->setIsActive(true);
|
||||
$cart->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets cart id
|
||||
*
|
||||
* @param string $cartId
|
||||
* @return int
|
||||
* @throws NoSuchEntityException
|
||||
*/
|
||||
private function getCartId(string $cartId)
|
||||
{
|
||||
$maskedQuoteIdToQuoteId = $this->objectManagerForTest->get(MaskedQuoteIdToQuoteIdInterface::class);
|
||||
return $maskedQuoteIdToQuoteId->execute($cartId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets cart id hash
|
||||
*
|
||||
* @param string $cartId
|
||||
* @return string
|
||||
* @throws NoSuchEntityException
|
||||
*/
|
||||
public function getCartIdHash(string $cartId): string
|
||||
{
|
||||
$getMaskedQuoteIdByReservedOrderId = $this->getTestObjectManager()
|
||||
->get(GetMaskedQuoteIdByReservedOrderId::class);
|
||||
return $getMaskedQuoteIdByReservedOrderId->execute($cartId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reset password token
|
||||
*
|
||||
* @param string $email
|
||||
* @return string
|
||||
* @throws LocalizedException
|
||||
* @throws NoSuchEntityException
|
||||
*/
|
||||
public function getResetPasswordToken(string $email): string
|
||||
{
|
||||
$accountManagement = $this->objectManagerForTest->get(AccountManagementInterface::class);
|
||||
$customerRegistry = $this->objectManagerForTest->get(CustomerRegistry::class);
|
||||
$accountManagement->initiatePasswordReset(
|
||||
$email,
|
||||
AccountManagement::EMAIL_RESET,
|
||||
1
|
||||
);
|
||||
|
||||
$customerSecure = $customerRegistry->retrieveSecureData(1);
|
||||
return $customerSecure->getRpToken();
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App\State;
|
||||
|
||||
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
|
||||
use Magento\TestFramework\ObjectManager as TestFrameworkObjectManager;
|
||||
use Weakmap;
|
||||
|
||||
/**
|
||||
* ObjectManager decorator used by GraphQlStateTest for resetting objects and getting initial properties from objects
|
||||
*/
|
||||
class ObjectManager extends TestFrameworkObjectManager
|
||||
{
|
||||
/**
|
||||
* Constructs this instance by copying test framework's ObjectManager
|
||||
*
|
||||
* @param TestFrameworkObjectManager $testFrameworkObjectManager
|
||||
*/
|
||||
public function __construct(TestFrameworkObjectManager $testFrameworkObjectManager)
|
||||
{
|
||||
/* Note: PHP doesn't have copy constructors, so we have to use get_object_vars,
|
||||
* but luckily all the properties in the superclass are protected. */
|
||||
$properties = get_object_vars($testFrameworkObjectManager);
|
||||
foreach ($properties as $key => $value) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
$this->_factory = new DynamicFactoryDecorator($this->_factory, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the WeakMap used by DynamicFactoryDecorator
|
||||
*
|
||||
* @return WeakMap
|
||||
*/
|
||||
public function getWeakMap() : WeakMap
|
||||
{
|
||||
return $this->_factory->getWeakMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns shared instances
|
||||
*
|
||||
* @return object[]
|
||||
*/
|
||||
public function getSharedInstances() : array
|
||||
{
|
||||
return $this->_sharedInstances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all factory objects that implement ResetAfterRequestInterface
|
||||
*/
|
||||
public function resetStateWeakMapObjects() : void
|
||||
{
|
||||
$this->_factory->_resetState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all objects sharing state & implementing ResetAfterRequestInterface
|
||||
*/
|
||||
public function resetStateSharedInstances() : void
|
||||
{
|
||||
/** @var object $object */
|
||||
foreach ($this->_sharedInstances as $object) {
|
||||
if ($object instanceof ResetAfterRequestInterface) {
|
||||
$object->_resetState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App\State;
|
||||
|
||||
// TODO: change this back into enum once magento-semvar is fixed
|
||||
class ShouldResetState
|
||||
{
|
||||
public const DoResetState = "DoResetState";
|
||||
public const DoNotResetState = "DoNotResetState";
|
||||
}
|
||||
@@ -1,694 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
/* These classes are skipped completely during comparison. */
|
||||
return [
|
||||
'navigationMenu' => [
|
||||
Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\ExtractDataFromCategoryTree::class => null,
|
||||
Magento\Customer\Model\Session::class => null,
|
||||
Magento\Framework\GraphQl\Query\Fields::class => null,
|
||||
Magento\Framework\Session\Generic::class => null,
|
||||
Magento\Framework\Module\ModuleList::class => null,
|
||||
Magento\Framework\Module\Manager::class => null,
|
||||
],
|
||||
'productDetailByName' => [
|
||||
Magento\Customer\Model\Session::class => null,
|
||||
Magento\Framework\GraphQl\Query\Fields::class => null,
|
||||
Magento\Framework\Session\Generic::class => null,
|
||||
Magento\Store\Model\GroupRepository::class => null,
|
||||
],
|
||||
'category' => [
|
||||
Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\ExtractDataFromCategoryTree::class => null,
|
||||
Magento\Framework\GraphQl\Query\Fields::class => null,
|
||||
],
|
||||
'productDetail' => [
|
||||
Magento\Framework\GraphQl\Query\Fields::class => null,
|
||||
],
|
||||
'resolveUrl' => [
|
||||
Magento\Framework\GraphQl\Query\Fields::class => null,
|
||||
],
|
||||
'createCustomer' => [
|
||||
Magento\Framework\Logger\LoggerProxy::class => null,
|
||||
Magento\Framework\View\Asset\PreProcessor\Helper\Sort::class => null,
|
||||
Magento\Framework\Filter\FilterManager::class => null,
|
||||
Magento\Store\Model\Address\Renderer::class => null,
|
||||
Magento\Customer\Model\CustomerRegistry::class => null,
|
||||
Magento\Eav\Model\ResourceModel\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\VersionControl\Metadata::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Address\Relation::class => null,
|
||||
Magento\Framework\Validator\Factory::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Address::class => null,
|
||||
Magento\Framework\Translate\Inline\ConfigInterface\Proxy::class => null,
|
||||
Magento\Framework\Translate\Inline::class => null,
|
||||
Magento\Framework\Json\Helper\Data::class => null,
|
||||
Magento\Directory\Helper\Data::class => null,
|
||||
Magento\TestFramework\Api\Config\Reader\FileResolver::class => null,
|
||||
Magento\Framework\Api\ExtensionAttribute\JoinProcessor::class => null,
|
||||
Magento\Customer\Model\ResourceModel\AddressRepository::class => null,
|
||||
Magento\Framework\Reflection\MethodsMap::class => null,
|
||||
Magento\Framework\Reflection\ExtensionAttributesProcessor\Proxy::class => null,
|
||||
Magento\Framework\Reflection\DataObjectProcessor::class => null,
|
||||
Magento\Framework\Api\DataObjectHelper::class => null,
|
||||
Magento\Customer\Model\AttributeMetadataConverter::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerMetadata::class => null,
|
||||
Magento\Customer\Model\Metadata\AttributeMetadataCache::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerCachedMetadata::class => null,
|
||||
Magento\Customer\Model\Config\Share::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Customer::class => null,
|
||||
Magento\Framework\Api\ImageProcessor::class => null,
|
||||
Magento\Customer\Model\Session\Proxy::class => null,
|
||||
Magento\Customer\Model\Delegation\Storage::class => null,
|
||||
Magento\Customer\Model\GroupRegistry::class => null,
|
||||
Magento\Framework\Model\ResourceModel\Db\VersionControl\Metadata::class => null,
|
||||
Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot::class => null,
|
||||
Magento\Tax\Model\TaxClass\Repository::class => null,
|
||||
Magento\Customer\Model\ResourceModel\GroupRepository::class => null,
|
||||
Magento\Customer\Model\ResourceModel\CustomerRepository::class => null,
|
||||
Magento\TestFramework\Mail\Template\TransportBuilderMock::class => null,
|
||||
Magento\Customer\Helper\View::class => null,
|
||||
Magento\Framework\Indexer\IndexerRegistry::class => null,
|
||||
Magento\Customer\Model\Customer::class => null,
|
||||
Magento\Framework\Session\SessionMaxSizeConfig::class => null,
|
||||
Magento\Framework\Session\SaveHandler::class => null,
|
||||
Magento\Paypal\Plugin\TransparentSessionChecker::class => null,
|
||||
Laminas\Uri\Uri::class => null,
|
||||
Magento\Backend\App\Area\FrontNameResolver::class => null,
|
||||
Magento\Backend\Helper\Data::class => null,
|
||||
Magento\GraphQl\Plugin\DisableSession::class => null,
|
||||
Magento\Framework\Session\Generic::class => null,
|
||||
Magento\Customer\Model\Session\SessionCleaner::class => null,
|
||||
Magento\Customer\Model\Authorization\CustomerSessionUserContext::class => null,
|
||||
Magento\JwtUserToken\Model\ResourceModel\FastStorageRevokedWrapper::class => null,
|
||||
Magento\Webapi\Model\Authorization\TokenUserContext::class => null,
|
||||
Magento\Authorization\Model\CompositeUserContext::class => null,
|
||||
Magento\Webapi\Model\WebapiRoleLocator::class => null,
|
||||
Magento\Customer\Model\Authentication::class => null,
|
||||
'CustomerAddressSnapshot' => null,
|
||||
'EavVersionControlSnapshot' => null,
|
||||
Magento\Catalog\Helper\Product\Flat\Indexer::class => null,
|
||||
Magento\Catalog\Helper\Product::class => null,
|
||||
Magento\Framework\Url\Helper\Data::class => null,
|
||||
Magento\Customer\Model\Session::class => null,
|
||||
Magento\Framework\Validator\EmailAddress::class => null,
|
||||
Magento\CustomerGraphQl\Model\Customer\ValidateCustomerData\ValidateEmail::class => null,
|
||||
Magento\CustomerGraphQl\Model\Customer\ValidateCustomerData::class => null,
|
||||
Magento\Newsletter\Model\CustomerSubscriberCache::class => null,
|
||||
Magento\Newsletter\Model\SubscriptionManager::class => null,
|
||||
Magento\LoginAsCustomerAssistance\Model\IsAssistanceEnabled::class => null,
|
||||
Magento\Framework\MessageQueue\Code\Generator\Config\RemoteServiceReader\Communication::class => null,
|
||||
Magento\Framework\Webapi\ServiceInputProcessor::class => null,
|
||||
Magento\Framework\MessageQueue\Publisher\Config\RemoteService\Reader::class => null,
|
||||
Magento\Framework\Pricing\Helper\Data::class => null,
|
||||
Magento\Catalog\Helper\Category::class => null,
|
||||
Magento\Catalog\Helper\Data::class => null,
|
||||
Magento\Tax\Helper\Data::class => null,
|
||||
Magento\Weee\Helper\Data::class => null,
|
||||
Magento\Quote\Model\Quote\Address\Total\Collector::class => null,
|
||||
Magento\Catalog\Helper\Product\Configuration::class => null,
|
||||
Magento\Bundle\Helper\Catalog\Product\Configuration::class => null,
|
||||
Magento\Eav\Model\AttributeDataFactory::class => null,
|
||||
Magento\PageCache\Model\Cache\Server::class => null,
|
||||
Magento\Catalog\Helper\Product\Edit\Action\Attribute::class => null,
|
||||
Magento\Newsletter\Model\Plugin\CustomerPlugin::class => null,
|
||||
Magento\Newsletter\Helper\Data::class => null,
|
||||
Magento\Developer\Helper\Data::class => null,
|
||||
Magento\Wishlist\Plugin\SaveWishlistDataAndAddReferenceKeyToBackUrl::class => null,
|
||||
Magento\Framework\View\Page\Config\Generator\Head::class => null,
|
||||
Magento\Store\Model\Argument\Interpreter\ServiceUrl::class => null,
|
||||
Magento\Framework\View\Layout\Argument\Interpreter\Url::class => null,
|
||||
Magento\Framework\Css\PreProcessor\Adapter\CssInliner::class => null,
|
||||
Magento\Framework\Module\ModuleList::class => null,
|
||||
Magento\Framework\Module\Manager::class => null,
|
||||
Magento\Authorization\Model\UserContextInterface\Proxy::class => null,
|
||||
Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper::class => null,
|
||||
Magento\Catalog\Model\Product\Attribute\Repository::class => null,
|
||||
Magento\Catalog\Model\ProductRepository::class => null,
|
||||
Magento\Framework\DataObject\Copy::class => null,
|
||||
Magento\Quote\Model\Quote\Item\Processor::class => null,
|
||||
Magento\Sales\Model\Config::class => null,
|
||||
Magento\Customer\Model\Session\Validators\CutoffValidator::class => null,
|
||||
Magento\Customer\Model\Session\Storage::class => null,
|
||||
Magento\Tax\Model\Calculation::class => null,
|
||||
Magento\OfflineShipping\Model\SalesRule\Calculator::class => null,
|
||||
Magento\SalesRule\Model\Validator::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order\Payment::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order\Status\History::class => null,
|
||||
Magento\Sales\Model\ResourceModel\Order::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Quote::class => null,
|
||||
Magento\Quote\Model\Quote::class => null,
|
||||
Magento\Backend\Model\Session::class => null,
|
||||
Magento\Checkout\Model\Session::class => null,
|
||||
Magento\Quote\Model\ResourceModel\Quote\Item::class => null,
|
||||
Magento\Backend\Model\Menu\Config::class => null,
|
||||
Magento\Backend\Model\Url::class => null,
|
||||
Magento\Customer\Model\Indexer\AttributeProvider::class => null,
|
||||
Magento\Framework\App\Cache\FlushCacheByTags::class => null,
|
||||
Magento\CustomerGraphQl\Model\Context\AddUserInfoToContext::class => null,
|
||||
Magento\Eav\Helper\Data::class => null,
|
||||
Magento\Framework\MessageQueue\DefaultValueProvider::class => null
|
||||
],
|
||||
'updateCustomer' => [
|
||||
Magento\Framework\Url\QueryParamsResolver::class => null,
|
||||
Magento\Framework\Registry::class => null,
|
||||
Magento\Customer\Model\AddressRegistry::class => null,
|
||||
Magento\Customer\Model\CustomerRegistry::class => null,
|
||||
Magento\Eav\Model\ResourceModel\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\VersionControl\Metadata::class => null,
|
||||
'CustomerAddressSnapshot' => null,
|
||||
Magento\Customer\Model\ResourceModel\Address\Relation::class => null,
|
||||
Magento\Framework\Validator\Factory::class => null,
|
||||
Magento\Customer\Api\CustomerRepositoryInterface\Proxy::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Address::class => null,
|
||||
Magento\Framework\Translate\Inline\ConfigInterface\Proxy::class => null,
|
||||
Magento\Framework\Translate\Inline::class => null,
|
||||
Magento\Framework\Json\Helper\Data::class => null,
|
||||
Magento\Directory\Helper\Data::class => null,
|
||||
Magento\TestFramework\Api\Config\Reader\FileResolver::class => null,
|
||||
Magento\Framework\Api\ExtensionAttribute\JoinProcessor::class => null,
|
||||
Magento\Customer\Model\ResourceModel\AddressRepository::class => null,
|
||||
Magento\Framework\Reflection\MethodsMap::class => null,
|
||||
Magento\Framework\Reflection\ExtensionAttributesProcessor\Proxy::class => null,
|
||||
Magento\Framework\Reflection\DataObjectProcessor::class => null,
|
||||
Magento\Framework\Api\DataObjectHelper::class => null,
|
||||
Magento\Customer\Model\AttributeMetadataConverter::class => null,
|
||||
Magento\Customer\Model\AttributeMetadataDataProvider::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerMetadata::class => null,
|
||||
Magento\Customer\Model\Metadata\AttributeMetadataCache::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerCachedMetadata::class => null,
|
||||
Magento\Customer\Model\Config\Share::class => null,
|
||||
'EavVersionControlSnapshot' => null,
|
||||
Magento\Customer\Model\AccountConfirmation::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Customer::class => null,
|
||||
Magento\Framework\Api\ImageProcessor::class => null,
|
||||
Magento\Customer\Model\Session\Proxy::class => null,
|
||||
Magento\Customer\Model\Delegation\Storage::class => null,
|
||||
Magento\Customer\Model\GroupRegistry::class => null,
|
||||
Magento\Framework\Model\ResourceModel\Db\VersionControl\Metadata::class => null,
|
||||
Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot::class => null,
|
||||
Magento\Tax\Model\TaxClass\Repository::class => null,
|
||||
Magento\Customer\Model\ResourceModel\GroupRepository::class => null,
|
||||
Magento\Customer\Model\ResourceModel\CustomerRepository::class => null,
|
||||
Magento\Customer\Helper\View::class => null,
|
||||
Magento\Framework\Indexer\IndexerRegistry::class => null,
|
||||
Magento\Customer\Model\Customer::class => null,
|
||||
Magento\Framework\Session\SessionMaxSizeConfig::class => null,
|
||||
Magento\Framework\Session\SaveHandler::class => null,
|
||||
Magento\Framework\Session\Storage::class => null,
|
||||
Magento\Paypal\Plugin\TransparentSessionChecker::class => null,
|
||||
Laminas\Uri\Uri::class => null,
|
||||
Magento\Backend\App\Area\FrontNameResolver::class => null,
|
||||
Magento\Backend\Helper\Data::class => null,
|
||||
Magento\GraphQl\Plugin\DisableSession::class => null,
|
||||
Magento\Framework\Session\Generic::class => null,
|
||||
Magento\Customer\Model\Session\SessionCleaner::class => null,
|
||||
Magento\Customer\Model\Authorization\CustomerSessionUserContext::class => null,
|
||||
Magento\JwtUserToken\Model\ConfigurableJwtSettingsProvider::class => null,
|
||||
Magento\JwtUserToken\Model\Reader::class => null,
|
||||
Magento\JwtUserToken\Model\ResourceModel\FastStorageRevokedWrapper::class => null,
|
||||
Magento\Webapi\Model\Authorization\TokenUserContext::class => null,
|
||||
Magento\Authorization\Model\CompositeUserContext::class => null,
|
||||
Magento\Webapi\Model\WebapiRoleLocator::class => null,
|
||||
Magento\Customer\Model\Authentication::class => null,
|
||||
Magento\Customer\Model\AccountManagement::class => null,
|
||||
Magento\Framework\MessageQueue\Code\Generator\Config\RemoteServiceReader\Communication::class => null,
|
||||
Magento\Framework\Webapi\ServiceInputProcessor::class => null,
|
||||
Magento\Framework\MessageQueue\Publisher\Config\RemoteService\Reader::class => null,
|
||||
Magento\Customer\Model\Session::class => null,
|
||||
Magento\Customer\Model\Plugin\CustomerFlushFormKey::class => null,
|
||||
Magento\CustomerGraphQl\Model\Context\AddUserInfoToContext::class => null,
|
||||
Magento\Tax\Model\Calculation::class => null,
|
||||
Magento\Catalog\Helper\Data::class => null,
|
||||
Magento\Checkout\Model\Session::class => null,
|
||||
Magento\Bundle\Pricing\Price\TaxPrice::class => null,
|
||||
Magento\Eav\Model\AttributeDataFactory::class => null,
|
||||
Magento\Customer\Observer\AfterAddressSaveObserver::class => null,
|
||||
Magento\LoginAsCustomer\Model\GetLoggedAsCustomerAdminId::class => null,
|
||||
Magento\LoginAsCustomerAssistance\Model\SetAssistance::class => null,
|
||||
Magento\LoginAsCustomerAssistance\Plugin\CustomerPlugin::class => null,
|
||||
Magento\CustomerGraphQl\Plugin\ClearCustomerSessionAfterRequest::class => null,
|
||||
Magento\Framework\Module\ModuleList::class => null,
|
||||
Magento\Framework\Module\Manager::class => null,
|
||||
Magento\Framework\Translate\Inline\Proxy::class => null,
|
||||
],
|
||||
'updateCustomerAddress' => [
|
||||
Magento\Framework\Url\QueryParamsResolver::class => null,
|
||||
Magento\Framework\Registry::class => null,
|
||||
Magento\Customer\Model\AddressRegistry::class => null,
|
||||
Magento\Customer\Model\CustomerRegistry::class => null,
|
||||
Magento\Eav\Model\ResourceModel\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\VersionControl\Metadata::class => null,
|
||||
'CustomerAddressSnapshot' => null,
|
||||
Magento\Customer\Model\ResourceModel\Address\Relation::class => null,
|
||||
Magento\Framework\Validator\Factory::class => null,
|
||||
Magento\Customer\Api\CustomerRepositoryInterface\Proxy::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Address::class => null,
|
||||
Magento\Framework\Translate\Inline\ConfigInterface\Proxy::class => null,
|
||||
Magento\Framework\Translate\Inline::class => null,
|
||||
Magento\Framework\Json\Helper\Data::class => null,
|
||||
Magento\Directory\Helper\Data::class => null,
|
||||
Magento\TestFramework\Api\Config\Reader\FileResolver::class => null,
|
||||
Magento\Framework\Api\ExtensionAttribute\JoinProcessor::class => null,
|
||||
Magento\Customer\Model\ResourceModel\AddressRepository::class => null,
|
||||
Magento\Framework\Reflection\MethodsMap::class => null,
|
||||
Magento\Framework\Reflection\ExtensionAttributesProcessor\Proxy::class => null,
|
||||
Magento\Framework\Reflection\DataObjectProcessor::class => null,
|
||||
Magento\Framework\Api\DataObjectHelper::class => null,
|
||||
Magento\Customer\Model\AttributeMetadataConverter::class => null,
|
||||
Magento\Customer\Model\AttributeMetadataDataProvider::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerMetadata::class => null,
|
||||
Magento\Customer\Model\Metadata\AttributeMetadataCache::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerCachedMetadata::class => null,
|
||||
Magento\Customer\Model\Config\Share::class => null,
|
||||
'EavVersionControlSnapshot' => null,
|
||||
Magento\Customer\Model\AccountConfirmation::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Customer::class => null,
|
||||
Magento\Framework\Api\ImageProcessor::class => null,
|
||||
Magento\Customer\Model\Session\Proxy::class => null,
|
||||
Magento\Customer\Model\Delegation\Storage::class => null,
|
||||
Magento\Tax\Model\TaxClass\Repository::class => null,
|
||||
Magento\Customer\Model\ResourceModel\CustomerRepository::class => null,
|
||||
Magento\Customer\Helper\View::class => null,
|
||||
Magento\Framework\Indexer\IndexerRegistry::class => null,
|
||||
Magento\Customer\Model\Customer::class => null,
|
||||
Magento\Framework\Session\SessionMaxSizeConfig::class => null,
|
||||
Magento\Framework\Session\SaveHandler::class => null,
|
||||
Magento\Framework\Session\Storage::class => null,
|
||||
Magento\Paypal\Plugin\TransparentSessionChecker::class => null,
|
||||
Laminas\Uri\Uri::class => null,
|
||||
Magento\Backend\App\Area\FrontNameResolver::class => null,
|
||||
Magento\Backend\Helper\Data::class => null,
|
||||
Magento\GraphQl\Plugin\DisableSession::class => null,
|
||||
Magento\Framework\Session\Generic::class => null,
|
||||
Magento\Customer\Model\Session\SessionCleaner::class => null,
|
||||
Magento\Customer\Model\Authorization\CustomerSessionUserContext::class => null,
|
||||
Magento\JwtUserToken\Model\ConfigurableJwtSettingsProvider::class => null,
|
||||
Magento\JwtUserToken\Model\Reader::class => null,
|
||||
Magento\JwtUserToken\Model\ResourceModel\FastStorageRevokedWrapper::class => null,
|
||||
Magento\Webapi\Model\Authorization\TokenUserContext::class => null,
|
||||
Magento\Authorization\Model\CompositeUserContext::class => null,
|
||||
Magento\Customer\Model\Authentication::class => null,
|
||||
Magento\Customer\Model\AccountManagement::class => null,
|
||||
Magento\Framework\MessageQueue\Code\Generator\Config\RemoteServiceReader\Communication::class => null,
|
||||
Magento\Framework\Webapi\ServiceInputProcessor::class => null,
|
||||
Magento\Framework\MessageQueue\Publisher\Config\RemoteService\Reader::class => null,
|
||||
Magento\Customer\Model\Session::class => null,
|
||||
Magento\Customer\Model\Plugin\CustomerFlushFormKey::class => null,
|
||||
Magento\CustomerGraphQl\Model\Context\AddUserInfoToContext::class => null,
|
||||
Magento\Tax\Model\Calculation::class => null,
|
||||
Magento\Eav\Model\AttributeDataFactory::class => null,
|
||||
Magento\Customer\Observer\AfterAddressSaveObserver::class => null,
|
||||
Magento\LoginAsCustomer\Model\GetLoggedAsCustomerAdminId::class => null,
|
||||
Magento\Framework\App\View::class => null,
|
||||
Magento\Framework\App\Action\Context::class => null,
|
||||
Magento\Catalog\Helper\Data::class => null,
|
||||
Magento\Checkout\Model\Session::class => null,
|
||||
Magento\Bundle\Pricing\Price\TaxPrice::class => null,
|
||||
Magento\CustomerGraphQl\Plugin\ClearCustomerSessionAfterRequest::class => null,
|
||||
Magento\Framework\Module\ModuleList::class => null,
|
||||
Magento\Framework\Module\Manager::class => null,
|
||||
Magento\Framework\Translate\Inline\Proxy::class => null,
|
||||
],
|
||||
'updateCustomerEmail' => [
|
||||
Magento\Framework\Url\QueryParamsResolver::class => null,
|
||||
Magento\Framework\Registry::class => null,
|
||||
Magento\Customer\Model\AddressRegistry::class => null,
|
||||
Magento\Customer\Model\CustomerRegistry::class => null,
|
||||
Magento\Eav\Model\ResourceModel\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\VersionControl\Metadata::class => null,
|
||||
'CustomerAddressSnapshot' => null,
|
||||
Magento\Customer\Model\ResourceModel\Address\Relation::class => null,
|
||||
Magento\Framework\Validator\Factory::class => null,
|
||||
Magento\Customer\Api\CustomerRepositoryInterface\Proxy::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Address::class => null,
|
||||
Magento\Framework\Translate\Inline\ConfigInterface\Proxy::class => null,
|
||||
Magento\Framework\Translate\Inline::class => null,
|
||||
Magento\Framework\Json\Helper\Data::class => null,
|
||||
Magento\Directory\Helper\Data::class => null,
|
||||
Magento\TestFramework\Api\Config\Reader\FileResolver::class => null,
|
||||
Magento\Framework\Api\ExtensionAttribute\JoinProcessor::class => null,
|
||||
Magento\Customer\Model\ResourceModel\AddressRepository::class => null,
|
||||
Magento\Framework\Reflection\MethodsMap::class => null,
|
||||
Magento\Framework\Reflection\ExtensionAttributesProcessor\Proxy::class => null,
|
||||
Magento\Framework\Reflection\DataObjectProcessor::class => null,
|
||||
Magento\Framework\Api\DataObjectHelper::class => null,
|
||||
Magento\Customer\Model\AttributeMetadataConverter::class => null,
|
||||
Magento\Customer\Model\AttributeMetadataDataProvider::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerMetadata::class => null,
|
||||
Magento\Customer\Model\Metadata\AttributeMetadataCache::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerCachedMetadata::class => null,
|
||||
Magento\Customer\Model\Config\Share::class => null,
|
||||
'EavVersionControlSnapshot' => null,
|
||||
Magento\Customer\Model\AccountConfirmation::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Customer::class => null,
|
||||
Magento\Framework\Api\ImageProcessor::class => null,
|
||||
Magento\Customer\Model\Session\Proxy::class => null,
|
||||
Magento\Customer\Model\Delegation\Storage::class => null,
|
||||
Magento\Customer\Model\GroupRegistry::class => null,
|
||||
Magento\Framework\Model\ResourceModel\Db\VersionControl\Metadata::class => null,
|
||||
Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot::class => null,
|
||||
Magento\Tax\Model\TaxClass\Repository::class => null,
|
||||
Magento\Customer\Model\ResourceModel\GroupRepository::class => null,
|
||||
Magento\Customer\Model\ResourceModel\CustomerRepository::class => null,
|
||||
Magento\Customer\Helper\View::class => null,
|
||||
Magento\Framework\Indexer\IndexerRegistry::class => null,
|
||||
Magento\Customer\Model\Customer::class => null,
|
||||
Magento\Framework\Session\SessionMaxSizeConfig::class => null,
|
||||
Magento\Framework\Session\SaveHandler::class => null,
|
||||
Magento\Framework\Session\Storage::class => null,
|
||||
Magento\Paypal\Plugin\TransparentSessionChecker::class => null,
|
||||
Laminas\Uri\Uri::class => null,
|
||||
Magento\Backend\App\Area\FrontNameResolver::class => null,
|
||||
Magento\Backend\Helper\Data::class => null,
|
||||
Magento\GraphQl\Plugin\DisableSession::class => null,
|
||||
Magento\Framework\Session\Generic::class => null,
|
||||
Magento\Customer\Model\Session\SessionCleaner::class => null,
|
||||
Magento\Customer\Model\Authorization\CustomerSessionUserContext::class => null,
|
||||
Magento\JwtUserToken\Model\ConfigurableJwtSettingsProvider::class => null,
|
||||
Magento\JwtUserToken\Model\Reader::class => null,
|
||||
Magento\JwtUserToken\Model\ResourceModel\FastStorageRevokedWrapper::class => null,
|
||||
Magento\Webapi\Model\Authorization\TokenUserContext::class => null,
|
||||
Magento\Authorization\Model\CompositeUserContext::class => null,
|
||||
Magento\Webapi\Model\WebapiRoleLocator::class => null,
|
||||
Magento\Customer\Model\Authentication::class => null,
|
||||
Magento\Customer\Model\AccountManagement::class => null,
|
||||
Magento\Framework\MessageQueue\Code\Generator\Config\RemoteServiceReader\Communication::class => null,
|
||||
Magento\Framework\Webapi\ServiceInputProcessor::class => null,
|
||||
Magento\Framework\MessageQueue\Publisher\Config\RemoteService\Reader::class => null,
|
||||
Magento\Customer\Model\Session::class => null,
|
||||
Magento\Customer\Model\Plugin\CustomerFlushFormKey::class => null,
|
||||
Magento\CustomerGraphQl\Model\Context\AddUserInfoToContext::class => null,
|
||||
Magento\Tax\Model\Calculation::class => null,
|
||||
Magento\Catalog\Helper\Data::class => null,
|
||||
Magento\Checkout\Model\Session::class => null,
|
||||
Magento\Bundle\Pricing\Price\TaxPrice::class => null,
|
||||
Magento\Eav\Model\AttributeDataFactory::class => null,
|
||||
Magento\Customer\Observer\AfterAddressSaveObserver::class => null,
|
||||
Magento\LoginAsCustomer\Model\GetLoggedAsCustomerAdminId::class => null,
|
||||
Magento\CustomerGraphQl\Plugin\ClearCustomerSessionAfterRequest::class => null,
|
||||
Magento\Framework\Module\ModuleList::class => null,
|
||||
Magento\Framework\Module\Manager::class => null,
|
||||
Magento\GraphQlCache\Model\Plugin\Auth\TokenIssuer::class => null,
|
||||
Magento\Framework\Validator\EmailAddress::class => null,
|
||||
Magento\CustomerGraphQl\Model\Customer\ValidateCustomerData\ValidateEmail::class => null,
|
||||
Magento\CustomerGraphQl\Model\Customer\ValidateCustomerData::class => null,
|
||||
Magento\Framework\App\View::class => null,
|
||||
Magento\Framework\App\Action\Context::class => null,
|
||||
Magento\Quote\Model\Quote\Address\Total\Collector::class => null,
|
||||
],
|
||||
'generateCustomerToken' => [
|
||||
Magento\Customer\Model\CustomerRegistry::class => null,
|
||||
Magento\Eav\Model\ResourceModel\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Set::class => null,
|
||||
Magento\Eav\Model\Entity\VersionControl\Metadata::class => null,
|
||||
'CustomerAddressSnapshot' => null,
|
||||
Magento\Customer\Model\ResourceModel\Address\Relation::class => null,
|
||||
Magento\Customer\Api\CustomerRepositoryInterface\Proxy::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Address::class => null,
|
||||
Magento\Framework\Translate\Inline\ConfigInterface\Proxy::class => null,
|
||||
Magento\Framework\Translate\Inline::class => null,
|
||||
Magento\Framework\Json\Helper\Data::class => null,
|
||||
Magento\Directory\Helper\Data::class => null,
|
||||
Magento\TestFramework\Api\Config\Reader\FileResolver::class => null,
|
||||
Magento\Framework\Api\ExtensionAttribute\JoinProcessor::class => null,
|
||||
Magento\Customer\Model\ResourceModel\AddressRepository::class => null,
|
||||
Magento\Framework\Reflection\MethodsMap::class => null,
|
||||
Magento\Framework\Reflection\ExtensionAttributesProcessor\Proxy::class => null,
|
||||
Magento\Framework\Reflection\DataObjectProcessor::class => null,
|
||||
Magento\Framework\Api\DataObjectHelper::class => null,
|
||||
Magento\Customer\Model\AttributeMetadataConverter::class => null,
|
||||
Magento\Customer\Model\AttributeMetadataDataProvider::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerMetadata::class => null,
|
||||
Magento\Customer\Model\Metadata\AttributeMetadataCache::class => null,
|
||||
Magento\Customer\Model\Metadata\CustomerCachedMetadata::class => null,
|
||||
Magento\Customer\Model\Config\Share::class => null,
|
||||
'EavVersionControlSnapshot' => null,
|
||||
Magento\Customer\Model\ResourceModel\Customer::class => null,
|
||||
Magento\Framework\Api\ImageProcessor::class => null,
|
||||
Magento\Customer\Model\Session\Proxy::class => null,
|
||||
Magento\Customer\Model\Delegation\Storage::class => null,
|
||||
Magento\Tax\Model\TaxClass\Repository::class => null,
|
||||
Magento\Customer\Model\ResourceModel\CustomerRepository::class => null,
|
||||
Magento\Customer\Helper\View::class => null,
|
||||
Magento\Customer\Model\Customer::class => null,
|
||||
Magento\Framework\Session\SessionMaxSizeConfig::class => null,
|
||||
Magento\Framework\Session\SaveHandler::class => null,
|
||||
Magento\Framework\Session\Storage::class => null,
|
||||
Magento\Paypal\Plugin\TransparentSessionChecker::class => null,
|
||||
Laminas\Uri\Uri::class => null,
|
||||
Magento\Backend\App\Area\FrontNameResolver::class => null,
|
||||
Magento\Backend\Helper\Data::class => null,
|
||||
Magento\GraphQl\Plugin\DisableSession::class => null,
|
||||
Magento\Framework\Session\Generic::class => null,
|
||||
Magento\Customer\Model\Session\SessionCleaner::class => null,
|
||||
Magento\Customer\Model\Authorization\CustomerSessionUserContext::class => null,
|
||||
Magento\JwtUserToken\Model\ConfigurableJwtSettingsProvider::class => null,
|
||||
Magento\JwtUserToken\Model\Reader::class => null,
|
||||
Magento\JwtUserToken\Model\ResourceModel\FastStorageRevokedWrapper::class => null,
|
||||
Magento\Webapi\Model\Authorization\TokenUserContext::class => null,
|
||||
Magento\Authorization\Model\CompositeUserContext::class => null,
|
||||
Magento\Customer\Model\Authentication::class => null,
|
||||
Magento\Customer\Model\Session::class => null,
|
||||
Magento\Framework\MessageQueue\Code\Generator\Config\RemoteServiceReader\Communication::class => null,
|
||||
Magento\Framework\Webapi\ServiceInputProcessor::class => null,
|
||||
Magento\Framework\MessageQueue\Publisher\Config\RemoteService\Reader::class => null,
|
||||
],
|
||||
'*' => [
|
||||
Magento\TestFramework\Interception\PluginList::class => null,
|
||||
// memory leak, wrong sql, potential issues
|
||||
Magento\Framework\Event\Config\Data::class => null,
|
||||
Magento\Framework\App\AreaList::class => null,
|
||||
Magento\Framework\App\DeploymentConfig::class => null,
|
||||
Magento\Theme\Model\View\Design::class => null,
|
||||
Magento\Framework\App\Cache\Frontend\Pool::class => null,
|
||||
Magento\Framework\App\Cache\Type\FrontendPool::class => null,
|
||||
Magento\Framework\App\DeploymentConfig\Writer::class => null,
|
||||
Magento\Framework\App\Cache\State::class => null,
|
||||
Magento\Framework\Module\ModuleList::class => null,
|
||||
Magento\RemoteStorage\Model\Config::class => null,
|
||||
Magento\Store\Model\Config\Processor\Fallback::class => null,
|
||||
Magento\Framework\Lock\LockBackendFactory::class => null,
|
||||
'customRemoteFilesystem' => null,
|
||||
'systemConfigQueryLocker' => null,
|
||||
Magento\Framework\View\Design\FileResolution\Fallback\TemplateFile::class => null,
|
||||
Magento\Config\App\Config\Source\RuntimeConfigSource::class => null,
|
||||
'scopesConfigInitialDataProvider' => null,
|
||||
Magento\Developer\Model\Logger\Handler\Debug::class => null,
|
||||
Magento\Developer\Model\Logger\Handler\Syslog::class => null,
|
||||
Magento\Store\App\Config\Source\RuntimeConfigSource::class => null,
|
||||
Magento\Store\App\Config\Type\Scopes::class => null,
|
||||
Magento\Framework\Module\Dir\Reader::class => null,
|
||||
Magento\Framework\Module\PackageInfo::class => null,
|
||||
Magento\Framework\App\Language\Dictionary::class => null,
|
||||
Magento\Framework\ObjectManager\ConfigInterface::class => null,
|
||||
Magento\Framework\App\Cache\Type\Config::class => null,
|
||||
Magento\Framework\Interception\PluginListGenerator::class => null,
|
||||
Magento\TestFramework\App\Config::class => null,
|
||||
Magento\TestFramework\Request::class => null,
|
||||
Magento\Framework\View\FileSystem::class => null,
|
||||
Magento\Framework\App\Config\FileResolver::class => null,
|
||||
Magento\TestFramework\ErrorLog\Logger::class => null,
|
||||
'translationConfigSourceAggregated' => null,
|
||||
Magento\Framework\App\Request\Http\Proxy::class => null,
|
||||
Magento\Framework\Event\Config\Reader\Proxy::class => null,
|
||||
Magento\Theme\Model\View\Design\Proxy::class => null,
|
||||
Magento\Translation\Model\Source\InitialTranslationSource\Proxy::class => null,
|
||||
Magento\Translation\App\Config\Type\Translation::class => null,
|
||||
Magento\Backend\App\Request\PathInfoProcessor\Proxy::class => null,
|
||||
Magento\Framework\View\Asset\Source::class => null,
|
||||
Magento\Framework\Translate\ResourceInterface\Proxy::class => null,
|
||||
Magento\Framework\Locale\Resolver\Proxy::class => null,
|
||||
Magento\MediaStorage\Helper\File\Storage\Database::class => null,
|
||||
Magento\Framework\App\Cache\Proxy::class => null,
|
||||
Magento\Framework\Translate::class => null,
|
||||
Magento\Store\Model\StoreManager::class => null,
|
||||
Magento\Framework\App\Http\Context::class => null,
|
||||
Magento\TestFramework\Response::class => null,
|
||||
Magento\Store\Model\WebsiteRepository::class => null,
|
||||
Magento\Framework\Locale\Resolver::class => null,
|
||||
Magento\Store\Model\GroupRepository::class => null,
|
||||
Magento\Store\Model\StoreRepository::class => null,
|
||||
Magento\Framework\View\Design\Fallback\RulePool::class => null,
|
||||
Magento\Framework\View\Asset\Repository::class => null,
|
||||
Magento\Framework\HTTP\Header::class => null,
|
||||
Magento\Framework\App\Route\Config::class => null,
|
||||
Magento\Store\Model\System\Store::class => null,
|
||||
Magento\AwsS3\Driver\CredentialsCache::class => null,
|
||||
Magento\Eav\Model\Config::class => null,
|
||||
'AssetPreProcessorPool' => null,
|
||||
Magento\GraphQl\Model\Query\ContextFactory::class => null,
|
||||
'viewFileMinifiedFallbackResolver' => null,
|
||||
Magento\Framework\View\Asset\Minification::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection::class => null,
|
||||
Magento\Framework\Url::class => null,
|
||||
Magento\Framework\HTTP\PhpEnvironment\RemoteAddress::class => null,
|
||||
Magento\Framework\Module\ModuleList::class => null,
|
||||
Magento\Framework\Module\Manager::class => null,
|
||||
/* AddUserInfoToContext has userContext changed by Magento\GraphQl\Model\Query\ContextFactory,
|
||||
* but we need to make this more robust in secure in case of unforeseen bugs.
|
||||
* resetState for userContext makes sense, but we need to make sure that it cannot copy current userContext. */
|
||||
Magento\CustomerGraphQl\Model\Context\AddUserInfoToContext::class => null, // FIXME: see above comment
|
||||
Magento\Framework\ObjectManager\DefinitionInterface::class => null,
|
||||
Magento\TestFramework\App\State::class => null,
|
||||
Magento\GraphQl\App\State\SkipListAndFilterList::class => null, // Yes, our test uses mutable state itself :-)
|
||||
Magento\Framework\App\ResourceConnection::class => null,
|
||||
Magento\Framework\App\ResourceConnection\Interceptor::class => null,
|
||||
Magento\Framework\Session\SaveHandler::class => null, // TODO: check this
|
||||
Magento\TestFramework\Db\Adapter\Mysql\Interceptor::class => null,
|
||||
],
|
||||
'*-fromConstructed' => [
|
||||
Magento\GraphQl\App\State\ObjectManager::class => null,
|
||||
Magento\RemoteStorage\Filesystem::class => null,
|
||||
Magento\Framework\App\Cache\Frontend\Factory::class => null,
|
||||
Magento\Framework\Config\Scope::class => null,
|
||||
Magento\TestFramework\ObjectManager\Config::class => null,
|
||||
Magento\Framework\ObjectManager\Definition\Runtime::class => null,
|
||||
Magento\Framework\Cache\LockGuardedCacheLoader::class => null,
|
||||
Magento\Config\App\Config\Type\System::class => null,
|
||||
Magento\Framework\View\Asset\PreProcessor\Pool::class => null,
|
||||
Magento\Framework\Xml\Parser::class => null, # TODO: why?!?! errorHandlerIsActive
|
||||
Magento\Framework\App\Area::class => null,
|
||||
Magento\Store\Model\Store\Interceptor::class => null,
|
||||
Magento\GraphQl\App\State\Comparator::class => null, // Yes, our test uses mutable state itself :-)
|
||||
Magento\Framework\GraphQl\Query\QueryParser::class =>
|
||||
null, // TODO: Do we need to add a reset for when config changes?
|
||||
Magento\Framework\App\Http\Context\Interceptor::class => null,
|
||||
Magento\Framework\HTTP\LaminasClient::class => null,
|
||||
Magento\Customer\Model\GroupRegistry::class =>
|
||||
null, // FIXME: This looks like it needs _resetState or else it would be bug
|
||||
Magento\Framework\Model\ResourceModel\Db\VersionControl\Metadata::class => null,
|
||||
Magento\Framework\App\DeploymentConfig::class => null,
|
||||
Laminas\Uri\Uri::class => null,
|
||||
Magento\Framework\App\Cache\Frontend\Pool::class => null,
|
||||
Magento\Framework\App\Cache\State::class =>
|
||||
null, // TODO: Need to confirm that this gets reset when poison pill triggers
|
||||
Magento\TestFramework\App\State\Interceptor::class => null,
|
||||
Magento\TestFramework\App\MutableScopeConfig::class => null,
|
||||
Magento\TestFramework\Store\StoreManager::class => null,
|
||||
Magento\TestFramework\Workaround\Override\Config\RelationsCollector::class => null,
|
||||
Magento\Framework\Translate\Inline::class =>
|
||||
null, // TODO: Need to confirm that this gets reset when poison pill triggers
|
||||
Magento\Framework\Reflection\MethodsMap::class => null,
|
||||
Magento\Framework\Session\SaveHandler::class => null,
|
||||
Magento\Customer\Model\GroupRegistry::class => null, // FIXME: Needs _resetState for $registry
|
||||
Magento\Customer\Model\Group\Interceptor::class => null,
|
||||
Magento\Store\Model\Group\Interceptor::class => null,
|
||||
Magento\Directory\Model\Currency\Interceptor::class => null,
|
||||
Magento\Theme\Model\Theme\ThemeProvider::class => null, // Needs _resetState for themes
|
||||
Magento\Theme\Model\View\Design::class => null,
|
||||
Magento\Catalog\Model\Category\AttributeRepository::class =>
|
||||
null, // FIXME: Needs resetState OR reset when poison pill triggered.
|
||||
Magento\Framework\Search\Request\Cleaner::class => null, // FIXME: Needs resetState
|
||||
Magento\Catalog\Model\ResourceModel\Category\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Attribute\Backend\DefaultBackend\Interceptor::class => null,
|
||||
Magento\GraphQlCache\Model\Resolver\IdentityPool::class => null,
|
||||
Magento\Inventory\Model\Stock::class => null,
|
||||
Magento\InventorySales\Model\SalesChannel::class => null,
|
||||
Magento\InventoryApi\Api\Data\StockExtension::class => null,
|
||||
Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Eav\Attribute\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Category\Attribute\Backend\Image\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Attribute\Backend\Startdate\Interceptor::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Backend\Datetime\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Category\Attribute\Backend\Sortby\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Category\Attribute\Backend\LayoutUpdate\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Attribute\Backend\Customlayoutupdate\Interceptor::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Backend\Time\Created\Interceptor::class => null,
|
||||
Magento\Eav\Model\Entity\AttributeBackendTime\Updated\Interceptor::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Backend\Increment\Interceptor::class => null,
|
||||
Magento\Eav\Model\Entity\Interceptor::class => null,
|
||||
Magento\Framework\View\Asset\RepositoryMap::class =>
|
||||
null, // TODO: does this need to reset on poison pill trigger?
|
||||
Magento\Framework\Url\RouteParamsResolver\Interceptor::class => null,
|
||||
Magento\Theme\Model\Theme::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Category\Collection\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Category\Interceptor::class => null,
|
||||
Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree\Wrapper\NodeWrapper::class => null,
|
||||
Magento\Framework\Api\AttributeValue::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Interceptor::class => null,
|
||||
Magento\Catalog\Model\ResourceModel\Product\Collection\Interceptor::class => null,
|
||||
Magento\Framework\Api\Search\SearchCriteria::class => null,
|
||||
Magento\Framework\Api\SortOrder::class => null,
|
||||
Magento\Framework\Api\Search\SearchResult::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Backend\Time\Updated\Interceptor::class => null,
|
||||
Magento\CatalogInventory\Model\Stock\Item\Interceptor::class => null,
|
||||
Magento\Framework\View\Asset\File::class => null,
|
||||
Magento\Customer\Model\Attribute\Interceptor::class => null,
|
||||
Magento\Framework\GraphQl\Schema\SchemaGenerator::class => null,
|
||||
Magento\Customer\Model\ResourceModel\Customer::class => null,
|
||||
Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot::class => null,
|
||||
Magento\Framework\App\PageCache\Version::class => null,
|
||||
Magento\Framework\App\PageCache\Identifier::class => null,
|
||||
Magento\Framework\App\PageCache\Kernel::class => null,
|
||||
Magento\Translation\Model\Source\InitialTranslationSource::class => null,
|
||||
Magento\Framework\GraphQl\Schema\Type\Output\OutputMapper::class => null,
|
||||
Magento\Framework\GraphQl\Schema\Type\Input\InputMapper::class => null,
|
||||
Magento\Framework\Filesystem\DriverPool::class => null,
|
||||
Magento\Framework\Filesystem\Directory\WriteFactory::class => null,
|
||||
Magento\Catalog\Model\Product\Media\Config::class => null,
|
||||
Magento\Catalog\Model\Product\Type\Interceptor::class =>
|
||||
null, // Note: We may need to check to see if this needs to be reset when config changes
|
||||
Magento\ConfigurableProduct\Model\Product\Type\Configurable\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Product\Type\Simple\Interceptor::class => null,
|
||||
Magento\Customer\Model\Session\Storage::class =>
|
||||
null, // FIXME: race condition with Magento\Customer\Model\Session::_resetState()
|
||||
Magento\Framework\Module\Manager::class => null,
|
||||
Magento\Eav\Api\Data\AttributeExtension::class
|
||||
=> null, // FIXME: This needs to be fixed. is_pagebuilder_enabled 0 => null
|
||||
Magento\TestFramework\Event\Magento::class => null,
|
||||
Magento\Staging\Model\VersionManager\Interceptor::class => null, // Has good _resetState
|
||||
Magento\Webapi\Model\Authorization\TokenUserContext::class => null, // Has good _resetState
|
||||
Magento\Store\Model\Website\Interceptor::class => null, // reset by poison pill
|
||||
Magento\Eav\Model\Entity\Type::class => null, // attribute types should be destroyed by poison pill
|
||||
Magento\Eav\Model\Entity\Attribute\Backend\DefaultBackend\Interceptor::class =>
|
||||
null, // attribute types should be destroyed by poison pill
|
||||
Magento\TestFramework\Mail\Template\TransportBuilderMock\Interceptor::class => null, // only for testing
|
||||
Magento\Customer\Model\Data\Customer::class =>
|
||||
null, // FIXME: looks like a bug. Why is this not destroyed?
|
||||
Magento\Customer\Model\Customer\Interceptor::class =>
|
||||
null, // FIXME: looks like a bug. Why is this not destroyed?
|
||||
Magento\Framework\ForeignKey\ObjectRelationProcessor\EnvironmentConfig::class =>
|
||||
null, // OK; shouldn't change outside of deployment
|
||||
Magento\Indexer\Model\Indexer\Interceptor::class =>
|
||||
null, // FIXME: looks like this needs to be reset ?
|
||||
Magento\Indexer\Model\Indexer\State::class =>
|
||||
null, // FIXME: looks like this needs to be reset ?
|
||||
Magento\Customer\Model\ResourceModel\Attribute\Collection\Interceptor::class =>
|
||||
null, // TODO: does this need to be fixed?
|
||||
Magento\Customer\Model\ResourceModel\Address\Attribute\Collection\Interceptor::class =>
|
||||
null, // TODO: why is this not getting destroyed?
|
||||
Magento\Customer\Model\Indexer\Address\AttributeProvider::class =>
|
||||
null, // TODO: I don't think this gets reset after poison pill, so it may need _resetState
|
||||
Magento\Customer\Model\Indexer\AttributeProvider::class =>
|
||||
null, // TODO: I don't think this gets reset after poison pill, so it may need _resetState
|
||||
Magento\Config\Model\Config\Structure\Data::class => null, // should be cleaned after poison pill
|
||||
Magento\Framework\Filter\Template\SignatureProvider::class =>
|
||||
null, // TODO: does this need _resetState?
|
||||
Magento\Customer\Model\ResourceModel\Address\Interceptor::class =>
|
||||
null, // customer_address_entity table info
|
||||
Magento\LoginAsCustomerAssistance\Model\IsAssistanceEnabled::class =>
|
||||
null, // FIXME: needs resetSate
|
||||
Magento\Quote\Model\Quote\Address\Total\Subtotal::class => null, // FIXME: these should not be reused.
|
||||
Magento\Quote\Model\Quote\Address\Total\Grand::class =>
|
||||
null, // FIXME: these should not be reused.
|
||||
Magento\SalesRule\Model\Quote\Address\Total\ShippingDiscount::class =>
|
||||
null, // FIXME: these should not be reused.
|
||||
Magento\Weee\Model\Total\Quote\WeeeTax::class => null, // FIXME: these should not be reused.
|
||||
Magento\Tax\Model\Sales\Total\Quote\Shipping\Interceptor::class => null, // FIXME: these should not be reused.
|
||||
Magento\Tax\Model\Sales\Total\Quote\Subtotal\Interceptor::class => null, // FIXME: these should not be reused.
|
||||
Magento\Ui\Config\Reader\FileResolver::class =>
|
||||
null, // TODO: confirm this gets reset from poison pill or is otherwise okay.
|
||||
Magento\Ui\Config\Converter::class =>
|
||||
null, // TODO: confirm this is cleaned when poison pill triggered
|
||||
],
|
||||
'' => [
|
||||
],
|
||||
];
|
||||
+57
-31
@@ -9,65 +9,91 @@
|
||||
*/
|
||||
namespace Magento\Sales\Block\Adminhtml\Order\Create\Form;
|
||||
|
||||
use Magento\Backend\App\Area\FrontNameResolver;
|
||||
use Magento\Backend\Block\Template\Context;
|
||||
use Magento\Backend\Model\Session\Quote;
|
||||
use Magento\Customer\Api\Data\AttributeMetadataInterfaceFactory;
|
||||
use Magento\Customer\Api\Data\OptionInterfaceFactory;
|
||||
use Magento\Customer\Api\Data\ValidationRuleInterfaceFactory;
|
||||
use Magento\Framework\Data\FormFactory;
|
||||
use Magento\Framework\Pricing\PriceCurrencyInterface;
|
||||
use Magento\Framework\Reflection\DataObjectProcessor;
|
||||
use Magento\Framework\View\DesignInterface;
|
||||
use Magento\Framework\View\Layout;
|
||||
use Magento\Sales\Model\AdminOrder\Create;
|
||||
use Magento\TestFramework\Helper\Bootstrap;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Class AbstractTest
|
||||
*
|
||||
* Test cases to check custom attribute can be added successfully with the form
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class AbstractTest extends \PHPUnit\Framework\TestCase
|
||||
class AbstractTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @magentoAppIsolation enabled
|
||||
*/
|
||||
public function testAddAttributesToForm()
|
||||
{
|
||||
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
|
||||
\Magento\TestFramework\Helper\Bootstrap::getInstance()
|
||||
->loadArea(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE);
|
||||
|
||||
$objectManager->get(\Magento\Framework\View\DesignInterface::class)->setDefaultDesignTheme();
|
||||
$objectManager = Bootstrap::getObjectManager();
|
||||
Bootstrap::getInstance()
|
||||
->loadArea(FrontNameResolver::AREA_CODE);
|
||||
$objectManager->get(DesignInterface::class)->setDefaultDesignTheme();
|
||||
$arguments = [
|
||||
$objectManager->get(\Magento\Backend\Block\Template\Context::class),
|
||||
$objectManager->get(\Magento\Backend\Model\Session\Quote::class),
|
||||
$objectManager->get(\Magento\Sales\Model\AdminOrder\Create::class),
|
||||
$objectManager->get(\Magento\Framework\Pricing\PriceCurrencyInterface::class),
|
||||
$objectManager->get(\Magento\Framework\Data\FormFactory::class),
|
||||
$objectManager->get(\Magento\Framework\Reflection\DataObjectProcessor::class)
|
||||
$objectManager->get(Context::class),
|
||||
$objectManager->get(Quote::class),
|
||||
$objectManager->get(Create::class),
|
||||
$objectManager->get(PriceCurrencyInterface::class),
|
||||
$objectManager->get(FormFactory::class),
|
||||
$objectManager->get(DataObjectProcessor::class)
|
||||
];
|
||||
|
||||
/** @var $block \Magento\Sales\Block\Adminhtml\Order\Create\Form\AbstractForm */
|
||||
/** @var $block AbstractForm */
|
||||
$block = $this->getMockForAbstractClass(
|
||||
\Magento\Sales\Block\Adminhtml\Order\Create\Form\AbstractForm::class,
|
||||
AbstractForm::class,
|
||||
$arguments
|
||||
);
|
||||
$block->setLayout($objectManager->create(\Magento\Framework\View\Layout::class));
|
||||
$block->setLayout($objectManager->create(Layout::class));
|
||||
|
||||
$method = new \ReflectionMethod(
|
||||
\Magento\Sales\Block\Adminhtml\Order\Create\Form\AbstractForm::class,
|
||||
$method1 = new ReflectionMethod(
|
||||
AbstractForm::class,
|
||||
'_addAttributesToForm'
|
||||
);
|
||||
$method->setAccessible(true);
|
||||
$method2 = new ReflectionMethod(
|
||||
AbstractForm::class,
|
||||
'getForm'
|
||||
);
|
||||
|
||||
/** @var $formFactory \Magento\Framework\Data\FormFactory */
|
||||
$formFactory = $objectManager->get(\Magento\Framework\Data\FormFactory::class);
|
||||
$form = $formFactory->create();
|
||||
$form = $method2->invoke($block);
|
||||
$fieldset = $form->addFieldset('test_fieldset', []);
|
||||
/** @var \Magento\Customer\Api\Data\AttributeMetadataInterfaceFactory $attributeMetadataFactory */
|
||||
/** @var AttributeMetadataInterfaceFactory $attributeMetadataFactory */
|
||||
$attributeMetadataFactory =
|
||||
$objectManager->create(\Magento\Customer\Api\Data\AttributeMetadataInterfaceFactory::class);
|
||||
$objectManager->create(AttributeMetadataInterfaceFactory::class);
|
||||
$dateAttribute = $attributeMetadataFactory->create()->setAttributeCode('date')
|
||||
->setBackendType('datetime')
|
||||
->setFrontendInput('date')
|
||||
->setFrontendLabel('Date');
|
||||
$attributes = ['date' => $dateAttribute];
|
||||
$method->invoke($block, $attributes, $fieldset);
|
||||
->setFrontendLabel('Date')
|
||||
->setSortOrder(100);
|
||||
|
||||
$element = $form->getElement('date');
|
||||
$this->assertNotNull($element);
|
||||
$this->assertNotEmpty($element->getDateFormat());
|
||||
$textAttribute = $attributeMetadataFactory->create()->setAttributeCode('test_text')
|
||||
->setBackendType('text')
|
||||
->setFrontendInput('text')
|
||||
->setFrontendLabel('Test Text')
|
||||
->setSortOrder(200);
|
||||
|
||||
$attributes = ['date' => $dateAttribute, 'test_text' => $textAttribute];
|
||||
$method1->invoke($block, $attributes, $fieldset);
|
||||
|
||||
$element1 = $form->getElement('date');
|
||||
$this->assertNotNull($element1);
|
||||
$this->assertNotEmpty($element1->getDateFormat());
|
||||
$this->assertNotEmpty($element1->getSortOrder());
|
||||
$this->assertEquals($element1->getSortOrder(), 100);
|
||||
|
||||
$element2 = $form->getElement('test_text');
|
||||
$this->assertNotNull($element2);
|
||||
$this->assertNotEmpty($element2->getSortOrder());
|
||||
$this->assertEquals($element2->getSortOrder(), 200);
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,7 @@ $payment->setMethod('checkmo');
|
||||
/** @var OrderItem $orderItem */
|
||||
$orderItem = $objectManager->create(OrderItem::class);
|
||||
$orderItem->setProductId($product->getId())->setQtyOrdered(2);
|
||||
$orderItem->setProductType(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE);
|
||||
|
||||
/** @var Order $order */
|
||||
$order = $objectManager->create(Order::class);
|
||||
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2023 Adobe
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* NOTICE: All information contained herein is, and remains
|
||||
* the property of Adobe and its suppliers, if any. The intellectual
|
||||
* and technical concepts contained herein are proprietary to Adobe
|
||||
* and its suppliers and are protected by all applicable intellectual
|
||||
* property laws, including trade secret and copyright laws.
|
||||
* Dissemination of this information or reproduction of this material
|
||||
* is strictly forbidden unless prior written permission is obtained
|
||||
* from Adobe.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\SalesRule\Model\Coupon;
|
||||
|
||||
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
|
||||
use Magento\Checkout\Test\Fixture\SetBillingAddress as SetBillingAddress;
|
||||
use Magento\Checkout\Test\Fixture\SetDeliveryMethod;
|
||||
use Magento\Checkout\Test\Fixture\SetPaymentMethod as SetPaymentMethod;
|
||||
use Magento\Checkout\Test\Fixture\SetShippingAddress as SetShippingAddress;
|
||||
use Magento\Customer\Test\Fixture\Customer;
|
||||
use Magento\Framework\MessageQueue\ConsumerFactory;
|
||||
use Magento\Quote\Api\CartManagementInterface;
|
||||
use Magento\Quote\Api\CartRepositoryInterface;
|
||||
use Magento\Quote\Api\CouponManagementInterface;
|
||||
use Magento\Quote\Test\Fixture\AddProductToCart;
|
||||
use Magento\Quote\Test\Fixture\CustomerCart;
|
||||
use Magento\Quote\Test\Fixture\GuestCart;
|
||||
use Magento\Sales\Api\OrderManagementInterface;
|
||||
use Magento\SalesRule\Test\Fixture\Rule as SalesRuleFixture;
|
||||
use Magento\TestFramework\Fixture\DataFixture;
|
||||
use Magento\TestFramework\Fixture\DataFixtureStorage;
|
||||
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
|
||||
use Magento\TestFramework\Helper\Bootstrap;
|
||||
use Magento\TestFramework\MessageQueue\ClearQueueProcessor;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class UpdateCouponUsagesTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var DataFixtureStorage
|
||||
*/
|
||||
private $fixtures;
|
||||
|
||||
/**
|
||||
* @var CouponManagementInterface
|
||||
*/
|
||||
private $couponManagement;
|
||||
|
||||
/**
|
||||
* @var CartManagementInterface
|
||||
*/
|
||||
private $cartManagement;
|
||||
|
||||
/**
|
||||
* @var CartRepositoryInterface
|
||||
*/
|
||||
private $cartRepository;
|
||||
|
||||
/**
|
||||
* @var OrderManagementInterface
|
||||
*/
|
||||
private $orderManagement;
|
||||
|
||||
/**
|
||||
* @var ConsumerFactory
|
||||
*/
|
||||
private $consumerFactory;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$objectManager = Bootstrap::getObjectManager();
|
||||
|
||||
$clearQueueProcessor = $objectManager->get(ClearQueueProcessor::class);
|
||||
$clearQueueProcessor->execute('sales.rule.update.coupon.usage');
|
||||
|
||||
$this->fixtures = $objectManager->get(DataFixtureStorageManager::class)->getStorage();
|
||||
$this->couponManagement = $objectManager->get(CouponManagementInterface::class);
|
||||
$this->cartManagement = $objectManager->get(CartManagementInterface::class);
|
||||
$this->cartRepository = $objectManager->get(CartRepositoryInterface::class);
|
||||
$this->orderManagement = $objectManager->get(OrderManagementInterface::class);
|
||||
$this->consumerFactory = $objectManager->get(ConsumerFactory::class);
|
||||
}
|
||||
|
||||
#[
|
||||
DataFixture(ProductFixture::class, as: 'p1'),
|
||||
DataFixture(
|
||||
SalesRuleFixture::class,
|
||||
['coupon_code' => 'one_per_customer', 'uses_per_customer' => 1, 'discount_amount' => 10]
|
||||
),
|
||||
DataFixture(Customer::class, as: 'customer'),
|
||||
|
||||
DataFixture(CustomerCart::class, ['customer_id' => '$customer.id$'], 'cart1'),
|
||||
DataFixture(AddProductToCart::class, ['cart_id' => '$cart1.id$', 'product_id' => '$p1.id$']),
|
||||
DataFixture(SetBillingAddress::class, ['cart_id' => '$cart1.id$']),
|
||||
DataFixture(SetShippingAddress::class, ['cart_id' => '$cart1.id$']),
|
||||
DataFixture(SetDeliveryMethod::class, ['cart_id' => '$cart1.id$']),
|
||||
DataFixture(SetPaymentMethod::class, ['cart_id' => '$cart1.id$']),
|
||||
|
||||
DataFixture(GuestCart::class, as: 'cart2'),
|
||||
DataFixture(AddProductToCart::class, ['cart_id' => '$cart2.id$', 'product_id' => '$p1.id$']),
|
||||
DataFixture(SetBillingAddress::class, ['cart_id' => '$cart2.id$']),
|
||||
DataFixture(SetShippingAddress::class, ['cart_id' => '$cart2.id$']),
|
||||
DataFixture(SetDeliveryMethod::class, ['cart_id' => '$cart2.id$']),
|
||||
DataFixture(SetPaymentMethod::class, ['cart_id' => '$cart2.id$']),
|
||||
]
|
||||
public function testCancelOrderBeforeUsageConsumerExecution(): void
|
||||
{
|
||||
$cart = $this->fixtures->get('cart1');
|
||||
$this->couponManagement->set($cart->getId(), 'one_per_customer');
|
||||
$orderId = $this->cartManagement->placeOrder($cart->getId());
|
||||
$this->orderManagement->cancel($orderId);
|
||||
$consumer = $this->consumerFactory->get('sales.rule.update.coupon.usage');
|
||||
$consumer->process(1);
|
||||
|
||||
$cart = $this->fixtures->get('cart2');
|
||||
$customer = $this->fixtures->get('customer');
|
||||
$this->cartManagement->assignCustomer($cart->getId(), $customer->getId(), 1);
|
||||
$cart = $this->cartRepository->get($cart->getId());
|
||||
$this->couponManagement->set($cart->getId(), 'one_per_customer');
|
||||
$this->cartManagement->placeOrder($cart->getId());
|
||||
$consumer->process(1);
|
||||
}
|
||||
}
|
||||
@@ -190,9 +190,9 @@ class DiscountTest extends TestCase
|
||||
[
|
||||
'bundle_cc',
|
||||
[
|
||||
'bundle_product_with_dynamic_price-simple1-simple2' => 0,
|
||||
'simple1' => 3,
|
||||
'simple2' => 7.99,
|
||||
'bundle_product_with_dynamic_price-simple1-simple2' => 10.99,
|
||||
'simple1' => 0,
|
||||
'simple2' => 0,
|
||||
],
|
||||
-10.99
|
||||
],
|
||||
|
||||
@@ -83,12 +83,34 @@ class CarrierTest extends TestCase
|
||||
'upsAuth' => $this->upsAuthMock]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testGetShipAcceptUrl()
|
||||
{
|
||||
$this->assertEquals('https://wwwcie.ups.com/ups.app/xml/ShipAccept', $this->carrier->getShipAcceptUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ship accept url for live site
|
||||
*
|
||||
* @magentoConfigFixture current_store carriers/ups/is_account_live 1
|
||||
*/
|
||||
public function testGetShipAcceptUrlLive()
|
||||
{
|
||||
$this->assertEquals('https://onlinetools.ups.com/ups.app/xml/ShipAccept', $this->carrier->getShipAcceptUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testGetShipConfirmUrl()
|
||||
{
|
||||
$this->assertEquals('https://wwwcie.ups.com/api/shipments/v1/ship', $this->carrier->getShipConfirmUrl());
|
||||
if ($this->carrier->getConfigData('type') == 'UPS_XML') {
|
||||
$this->assertEquals('https://wwwcie.ups.com/ups.app/xml/ShipConfirm', $this->carrier->getShipConfirmUrl());
|
||||
} else {
|
||||
$this->assertEquals('https://wwwcie.ups.com/api/shipments/v1/ship', $this->carrier->getShipConfirmUrl());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,16 +120,24 @@ class CarrierTest extends TestCase
|
||||
*/
|
||||
public function testGetShipConfirmUrlLive()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'https://onlinetools.ups.com/api/shipments/v1/ship',
|
||||
$this->carrier->getShipConfirmUrl()
|
||||
);
|
||||
if ($this->carrier->getConfigData('type') == 'UPS_XML') {
|
||||
$this->assertEquals(
|
||||
'https://onlinetools.ups.com/ups.app/xml/ShipConfirm',
|
||||
$this->carrier->getShipConfirmUrl()
|
||||
);
|
||||
} else {
|
||||
$this->assertEquals(
|
||||
'https://onlinetools.ups.com/api/shipments/v1/ship',
|
||||
$this->carrier->getShipConfirmUrl()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect rates for UPS Ground method.
|
||||
*
|
||||
* @magentoConfigFixture current_store carriers/ups/active 1
|
||||
* @magentoConfigFixture current_store carriers/ups/type UPS_REST
|
||||
* @magentoConfigFixture current_store carriers/ups/allowed_methods 03
|
||||
* @magentoConfigFixture current_store carriers/ups/free_method 03
|
||||
* @magentoConfigFixture default_store carriers/ups/shipper_number 12345
|
||||
@@ -168,6 +198,7 @@ class CarrierTest extends TestCase
|
||||
* @dataProvider collectRatesDataProvider
|
||||
* @magentoConfigFixture default_store shipping/origin/country_id GB
|
||||
* @magentoConfigFixture default_store carriers/ups/active 1
|
||||
* @magentoConfigFixture current_store carriers/ups/type UPS_REST
|
||||
* @magentoConfigFixture default_store carriers/ups/shipper_number 12345
|
||||
* @magentoConfigFixture default_store carriers/ups/origin_shipment Shipments Originating in the European Union
|
||||
* @magentoConfigFixture default_store carriers/ups/username user
|
||||
@@ -230,6 +261,7 @@ class CarrierTest extends TestCase
|
||||
* @return void
|
||||
* @magentoConfigFixture default_store shipping/origin/country_id GB
|
||||
* @magentoConfigFixture default_store carriers/ups/active 1
|
||||
* @magentoConfigFixture default_store carriers/ups/type UPS_REST
|
||||
* @magentoConfigFixture default_store carriers/ups/shipper_number 12345
|
||||
* @magentoConfigFixture default_store carriers/ups/origin_shipment Shipments Originating in the European Union
|
||||
* @magentoConfigFixture default_store carriers/ups/username user
|
||||
@@ -287,6 +319,7 @@ class CarrierTest extends TestCase
|
||||
*
|
||||
* @magentoConfigFixture default_store shipping/origin/country_id GB
|
||||
* @magentoConfigFixture default_store carriers/ups/active 1
|
||||
* @magentoConfigFixture default_store carriers/ups/type UPS_REST
|
||||
* @magentoConfigFixture default_store carriers/ups/shipper_number 12345
|
||||
* @magentoConfigFixture default_store carriers/ups/origin_shipment Shipments Originating in the European Union
|
||||
* @magentoConfigFixture default_store carriers/ups/username user
|
||||
@@ -380,6 +413,7 @@ class CarrierTest extends TestCase
|
||||
*
|
||||
* @magentoConfigFixture default_store shipping/origin/country_id GB
|
||||
* @magentoConfigFixture default_store carriers/ups/active 1
|
||||
* @magentoConfigFixture default_store carriers/ups/type UPS_REST
|
||||
* @magentoConfigFixture default_store carriers/ups/shipper_number 12345
|
||||
* @magentoConfigFixture default_store carriers/ups/origin_shipment Shipments Originating in the European Union
|
||||
* @magentoConfigFixture default_store carriers/ups/username user
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Magento\Test\Integrity\Library;
|
||||
|
||||
use Laminas\Code\Reflection\ClassReflection;
|
||||
use Laminas\Code\Reflection\Exception\InvalidArgumentException;
|
||||
use Magento\Framework\App\Utility\AggregateInvoker;
|
||||
use Magento\Framework\App\Utility\Files;
|
||||
use Magento\Framework\Component\ComponentRegistrar;
|
||||
use Magento\Setup\Module\Di\Code\Reader\FileClassScanner;
|
||||
@@ -60,7 +61,7 @@ class DependencyTest extends TestCase
|
||||
|
||||
public function testCheckDependencies(): void
|
||||
{
|
||||
$invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this);
|
||||
$invoker = new AggregateInvoker($this);
|
||||
$invoker(
|
||||
/**
|
||||
* @param string $file
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
/**
|
||||
* An ultimate accessor to cache types' statuses
|
||||
*
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
@@ -10,49 +8,54 @@ namespace Magento\Framework\App\Cache;
|
||||
use Magento\Framework\App\DeploymentConfig;
|
||||
use Magento\Framework\App\DeploymentConfig\Writer;
|
||||
use Magento\Framework\Config\File\ConfigFilePool;
|
||||
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
|
||||
|
||||
/**
|
||||
* Cache State
|
||||
*/
|
||||
class State implements StateInterface
|
||||
class State implements StateInterface, ResetAfterRequestInterface
|
||||
{
|
||||
/**
|
||||
* Disallow cache
|
||||
*/
|
||||
const PARAM_BAN_CACHE = 'global_ban_use_cache';
|
||||
public const PARAM_BAN_CACHE = 'global_ban_use_cache';
|
||||
|
||||
/**
|
||||
* Deployment config key
|
||||
*/
|
||||
const CACHE_KEY = 'cache_types';
|
||||
public const CACHE_KEY = 'cache_types';
|
||||
|
||||
/**
|
||||
* Deployment configuration
|
||||
*
|
||||
* @var DeploymentConfig
|
||||
* phpcs:disable Magento2.Commenting.ClassPropertyPHPDocFormatting
|
||||
*/
|
||||
private $config;
|
||||
private readonly DeploymentConfig $config;
|
||||
|
||||
/**
|
||||
* Deployment configuration storage writer
|
||||
*
|
||||
* @var Writer
|
||||
*
|
||||
* phpcs:disable Magento2.Commenting.ClassPropertyPHPDocFormatting
|
||||
*/
|
||||
private $writer;
|
||||
private readonly Writer $writer;
|
||||
|
||||
/**
|
||||
* Associative array of cache type codes and their statuses (enabled/disabled)
|
||||
*
|
||||
* @var array
|
||||
* @var array|null
|
||||
*/
|
||||
private $statuses;
|
||||
private ?array $statuses = null;
|
||||
|
||||
/**
|
||||
* Whether all cache types are forced to be disabled
|
||||
*
|
||||
* @var bool
|
||||
* phpcs:disable Magento2.Commenting.ClassPropertyPHPDocFormatting
|
||||
*/
|
||||
private $banAll;
|
||||
private readonly bool $banAll;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -74,7 +77,7 @@ class State implements StateInterface
|
||||
* @param string $cacheType
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled($cacheType)
|
||||
public function isEnabled($cacheType): bool
|
||||
{
|
||||
$this->load();
|
||||
return (bool)($this->statuses[$cacheType] ?? false);
|
||||
@@ -87,7 +90,7 @@ class State implements StateInterface
|
||||
* @param bool $isEnabled
|
||||
* @return void
|
||||
*/
|
||||
public function setEnabled($cacheType, $isEnabled)
|
||||
public function setEnabled($cacheType, $isEnabled): void
|
||||
{
|
||||
$this->load();
|
||||
$this->statuses[$cacheType] = (int)$isEnabled;
|
||||
@@ -97,8 +100,9 @@ class State implements StateInterface
|
||||
* Save the current statuses (enabled/disabled) of cache types to the persistent storage
|
||||
*
|
||||
* @return void
|
||||
* @throws \Magento\Framework\Exception\FileSystemException
|
||||
*/
|
||||
public function persist()
|
||||
public function persist(): void
|
||||
{
|
||||
$this->load();
|
||||
$this->writer->saveConfig([ConfigFilePool::APP_ENV => [self::CACHE_KEY => $this->statuses]]);
|
||||
@@ -108,8 +112,10 @@ class State implements StateInterface
|
||||
* Load statuses (enabled/disabled) of cache types
|
||||
*
|
||||
* @return void
|
||||
* @throws \Magento\Framework\Exception\FileSystemException
|
||||
* @throws \Magento\Framework\Exception\RuntimeException
|
||||
*/
|
||||
private function load()
|
||||
private function load(): void
|
||||
{
|
||||
if (null === $this->statuses) {
|
||||
$this->statuses = [];
|
||||
@@ -119,4 +125,12 @@ class State implements StateInterface
|
||||
$this->statuses = $this->config->getConfigData(self::CACHE_KEY) ?: [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function _resetState(): void
|
||||
{
|
||||
$this->statuses = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
namespace Magento\Framework\App\State;
|
||||
|
||||
use Magento\Framework\App\Config\ScopeCodeResolver;
|
||||
use Magento\Framework\App\DeploymentConfig;
|
||||
|
||||
/**
|
||||
* Framework specific reset state
|
||||
*/
|
||||
class ReloadProcessor implements ReloadProcessorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param DeploymentConfig $deploymentConfig
|
||||
* @param ScopeCodeResolver $scopeCodeResolver
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly DeploymentConfig $deploymentConfig,
|
||||
private readonly ScopeCodeResolver $scopeCodeResolver
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the system state to reload itself.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reloadState(): void
|
||||
{
|
||||
$this->deploymentConfig->resetData();
|
||||
$this->scopeCodeResolver->clean();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
namespace Magento\Framework\App\State;
|
||||
|
||||
/**
|
||||
* Composite of reload processors
|
||||
*/
|
||||
class ReloadProcessorComposite implements ReloadProcessorInterface
|
||||
{
|
||||
/**
|
||||
* @param ReloadProcessorInterface[] $processors
|
||||
*/
|
||||
public function __construct(private array $processors)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function reloadState(): void
|
||||
{
|
||||
ksort($this->processors);
|
||||
/** @var ReloadProcessorInterface $processor */
|
||||
foreach ($this->processors as $processor) {
|
||||
$processor->reloadState();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
namespace Magento\Framework\App\State;
|
||||
|
||||
interface ReloadProcessorInterface
|
||||
{
|
||||
/**
|
||||
* Tells the system state to reload itself.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reloadState(): void;
|
||||
}
|
||||
@@ -77,17 +77,22 @@ class Data implements \Magento\Framework\Config\DataInterface
|
||||
* @param CacheInterface $cache
|
||||
* @param string $cacheId
|
||||
* @param SerializerInterface|null $serializer
|
||||
* @param array|null $cacheTags
|
||||
*/
|
||||
public function __construct(
|
||||
ReaderInterface $reader,
|
||||
CacheInterface $cache,
|
||||
$cacheId,
|
||||
SerializerInterface $serializer = null
|
||||
SerializerInterface $serializer = null,
|
||||
?array $cacheTags = null,
|
||||
) {
|
||||
$this->reader = $reader;
|
||||
$this->cache = $cache;
|
||||
$this->cacheId = $cacheId;
|
||||
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
|
||||
if ($cacheTags) {
|
||||
$this->cacheTags = $cacheTags;
|
||||
}
|
||||
$this->initData();
|
||||
}
|
||||
|
||||
|
||||
@@ -328,8 +328,13 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface, Rese
|
||||
}
|
||||
if ($this->_transactionLevel === 0) {
|
||||
$this->logger->startTimer();
|
||||
parent::beginTransaction();
|
||||
$this->logger->logStats(LoggerInterface::TYPE_TRANSACTION, 'BEGIN');
|
||||
try {
|
||||
$this->performQuery(function () {
|
||||
parent::beginTransaction();
|
||||
});
|
||||
} finally {
|
||||
$this->logger->logStats(LoggerInterface::TYPE_TRANSACTION, 'BEGIN');
|
||||
}
|
||||
}
|
||||
++$this->_transactionLevel;
|
||||
return $this;
|
||||
@@ -598,9 +603,30 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface, Rese
|
||||
* @return \Zend_Db_Statement_Pdo|void
|
||||
* @throws Zend_Db_Adapter_Exception To re-throw \PDOException.
|
||||
* @throws Zend_Db_Statement_Exception
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
protected function _query($sql, $bind = [])
|
||||
{
|
||||
$result = null;
|
||||
try {
|
||||
$this->_checkDdlTransaction($sql);
|
||||
$this->_prepareQuery($sql, $bind);
|
||||
$this->logger->startTimer();
|
||||
$result = $this->performQuery(fn () => parent::query($sql, $bind));
|
||||
} finally {
|
||||
$this->logger->logStats(LoggerInterface::TYPE_QUERY, $sql, $bind, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute query and reconnect if needed.
|
||||
*
|
||||
* @param callable $queryExecutor
|
||||
* @return \Zend_Db_Statement_Pdo|void
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function performQuery(callable $queryExecutor)
|
||||
{
|
||||
$connectionErrors = [
|
||||
2006, // SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
|
||||
@@ -609,22 +635,15 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface, Rese
|
||||
$triesCount = 0;
|
||||
do {
|
||||
$retry = false;
|
||||
$this->logger->startTimer();
|
||||
try {
|
||||
$this->_checkDdlTransaction($sql);
|
||||
$this->_prepareQuery($sql, $bind);
|
||||
$result = parent::query($sql, $bind);
|
||||
$this->logger->logStats(LoggerInterface::TYPE_QUERY, $sql, $bind, $result);
|
||||
return $result;
|
||||
return $queryExecutor();
|
||||
} catch (\Exception $e) {
|
||||
// Finalize broken query
|
||||
$profiler = $this->getProfiler();
|
||||
if ($profiler instanceof Profiler) {
|
||||
/** @var Profiler $profiler */
|
||||
$profiler->queryEndLast();
|
||||
}
|
||||
|
||||
/** @var $pdoException \PDOException */
|
||||
$pdoException = null;
|
||||
if ($e instanceof \PDOException) {
|
||||
$pdoException = $e;
|
||||
@@ -641,12 +660,10 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface, Rese
|
||||
$retry = true;
|
||||
$triesCount++;
|
||||
$this->closeConnection();
|
||||
|
||||
$this->_connect();
|
||||
}
|
||||
|
||||
if (!$retry) {
|
||||
$this->logger->logStats(LoggerInterface::TYPE_QUERY, $sql, $bind);
|
||||
$this->logger->critical($e);
|
||||
// rethrow custom exception if needed
|
||||
if ($pdoException && isset($this->exceptionMap[$pdoException->errorInfo[1]])) {
|
||||
|
||||
@@ -33,12 +33,6 @@ class BatchRangeIterator implements BatchIteratorInterface
|
||||
*/
|
||||
private $rangeField;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @deprecated 102.0.0 unused class property
|
||||
*/
|
||||
private $rangeFieldAlias;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
@@ -87,19 +81,19 @@ class BatchRangeIterator implements BatchIteratorInterface
|
||||
* @param string $correlationName
|
||||
* @param string|array $rangeField
|
||||
* @param string $rangeFieldAlias @deprecated
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
public function __construct(
|
||||
Select $select,
|
||||
$batchSize,
|
||||
$correlationName,
|
||||
$rangeField,
|
||||
$rangeFieldAlias
|
||||
$rangeFieldAlias = ''
|
||||
) {
|
||||
$this->batchSize = $batchSize;
|
||||
$this->select = $select;
|
||||
$this->correlationName = $correlationName;
|
||||
$this->rangeField = $rangeField;
|
||||
$this->rangeFieldAlias = $rangeFieldAlias;
|
||||
$this->connection = $select->getConnection();
|
||||
}
|
||||
|
||||
|
||||
@@ -866,4 +866,81 @@ class MysqlTest extends TestCase
|
||||
|
||||
return $method->invokeArgs($adapter, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider retryExceptionDataProvider
|
||||
* @param \Exception $exception
|
||||
* @return void
|
||||
*/
|
||||
public function testBeginTransactionWithReconnect(\Exception $exception): void
|
||||
{
|
||||
$adapter = $this->getMysqlPdoAdapterMock(['_connect', '_beginTransaction', '_rollBack']);
|
||||
$adapter->expects(self::exactly(4))
|
||||
->method('_connect');
|
||||
$adapter->expects(self::once())
|
||||
->method('_rollBack');
|
||||
|
||||
$matcher = self::exactly(2);
|
||||
$adapter->expects($matcher)
|
||||
->method('_beginTransaction')
|
||||
->willReturnCallback(
|
||||
function () use ($matcher, $exception) {
|
||||
if ($matcher->getInvocationCount() === 1) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
);
|
||||
$adapter->beginTransaction();
|
||||
$adapter->rollBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function retryExceptionDataProvider(): array
|
||||
{
|
||||
$serverHasGoneAwayException = new \PDOException();
|
||||
$serverHasGoneAwayException->errorInfo = [1 => 2006];
|
||||
$lostConnectionException = new \PDOException();
|
||||
$lostConnectionException->errorInfo = [1 => 2013];
|
||||
|
||||
return [
|
||||
[$serverHasGoneAwayException],
|
||||
[$lostConnectionException],
|
||||
[new \Zend_Db_Statement_Exception('', 0, $serverHasGoneAwayException)],
|
||||
[new \Zend_Db_Statement_Exception('', 0, $lostConnectionException)],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider exceptionDataProvider
|
||||
* @param \Exception $exception
|
||||
* @return void
|
||||
*/
|
||||
public function testBeginTransactionWithoutReconnect(\Exception $exception): void
|
||||
{
|
||||
$this->expectException(\Exception::class);
|
||||
$adapter = $this->getMysqlPdoAdapterMock(['_connect', '_beginTransaction', '_rollBack']);
|
||||
$adapter->expects(self::once())
|
||||
->method('_connect');
|
||||
$adapter->expects(self::once())
|
||||
->method('_beginTransaction')
|
||||
->willThrowException($exception);
|
||||
$adapter->beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function exceptionDataProvider(): array
|
||||
{
|
||||
$pdoException = new \PDOException();
|
||||
$pdoException->errorInfo = [1 => 1213];
|
||||
|
||||
return [
|
||||
[$pdoException],
|
||||
[new \Zend_Db_Statement_Exception('', 0, $pdoException)],
|
||||
[new \Exception()],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ namespace Magento\Framework;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionParameter;
|
||||
use Magento\Framework\Interception\Code\InterfaceValidator;
|
||||
|
||||
/**
|
||||
* Returns a reflection parameter's class if possible.
|
||||
@@ -30,8 +31,16 @@ trait GetParameterClassTrait
|
||||
return null;
|
||||
}
|
||||
|
||||
return $parameterType && !$parameterType->isBuiltin()
|
||||
? new ReflectionClass($parameterType->getName())
|
||||
: null;
|
||||
// get $parameterType package name
|
||||
$parameterPackage = strstr(trim((string)$parameterType), "\\", true);
|
||||
|
||||
if ($parameterType
|
||||
&& !$parameterType->isBuiltin()
|
||||
&& !in_array($parameterPackage, InterfaceValidator::$optionalPackages)
|
||||
) {
|
||||
return new ReflectionClass($parameterType->getName());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,16 @@ class InterfaceValidator
|
||||
*/
|
||||
protected $_argumentsReader;
|
||||
|
||||
/**
|
||||
* List of optional packages
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $optionalPackages = [
|
||||
'Swoole',
|
||||
'OpenSwoole'
|
||||
];
|
||||
|
||||
/**
|
||||
* @param ArgumentsReader $argumentsReader
|
||||
*/
|
||||
@@ -50,6 +60,12 @@ class InterfaceValidator
|
||||
*/
|
||||
public function validate($pluginClass, $interceptedType)
|
||||
{
|
||||
// check if $interceptedType is a part of optional package
|
||||
$interceptedPackage = strstr(trim((string)$interceptedType), "\\", true);
|
||||
if (in_array($interceptedPackage, self::$optionalPackages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$interceptedType = '\\' . trim((string)$interceptedType, '\\');
|
||||
$pluginClass = '\\' . trim((string)$pluginClass, '\\');
|
||||
$plugin = new \ReflectionClass($pluginClass);
|
||||
|
||||
@@ -57,8 +57,12 @@ class Builder implements ResetAfterRequestInterface
|
||||
* @param Binder $binder
|
||||
* @param Cleaner $cleaner
|
||||
*/
|
||||
public function __construct(ObjectManagerInterface $objectManager, Config $config, Binder $binder, Cleaner $cleaner)
|
||||
{
|
||||
public function __construct(
|
||||
ObjectManagerInterface $objectManager,
|
||||
Config $config,
|
||||
Binder $binder,
|
||||
Cleaner $cleaner
|
||||
) {
|
||||
$this->objectManager = $objectManager;
|
||||
$this->config = $config;
|
||||
$this->binder = $binder;
|
||||
@@ -153,6 +157,7 @@ class Builder implements ResetAfterRequestInterface
|
||||
$requestName = $this->data['requestName'];
|
||||
/** @var array $data */
|
||||
$data = $this->config->get($requestName);
|
||||
|
||||
if ($data === null) {
|
||||
throw new NonExistingRequestNameException(new Phrase("Request name '%1' doesn't exist.", [$requestName]));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class Config extends \Magento\Framework\Config\Data
|
||||
/**
|
||||
* Cache identifier
|
||||
*/
|
||||
const CACHE_ID = 'request_declaration';
|
||||
public const CACHE_ID = 'request_declaration';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -24,13 +24,16 @@ class Config extends \Magento\Framework\Config\Data
|
||||
* @param \Magento\Framework\Config\CacheInterface $cache
|
||||
* @param string|null $cacheId
|
||||
* @param SerializerInterface|null $serializer
|
||||
* @param array|null $cacheTags
|
||||
* phpcs:disable Generic.CodeAnalysis.UselessOverridingMethod
|
||||
*/
|
||||
public function __construct(
|
||||
\Magento\Framework\Search\Request\Config\FilesystemReader $reader,
|
||||
\Magento\Framework\Config\CacheInterface $cache,
|
||||
$cacheId = self::CACHE_ID,
|
||||
SerializerInterface $serializer = null
|
||||
SerializerInterface $serializer = null,
|
||||
?array $cacheTags = null,
|
||||
) {
|
||||
parent::__construct($reader, $cache, $cacheId, $serializer);
|
||||
parent::__construct($reader, $cache, $cacheId, $serializer, $cacheTags);
|
||||
}
|
||||
}
|
||||
@@ -248,11 +248,12 @@ class PatchApplier
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$schemaPatchClass = is_object($schemaPatch) ? get_class($schemaPatch) : $schemaPatch;
|
||||
throw new SetupException(
|
||||
new Phrase(
|
||||
'Unable to apply patch %1 for module %2. Original exception message: %3',
|
||||
[
|
||||
get_class($schemaPatch),
|
||||
$schemaPatchClass,
|
||||
$moduleName,
|
||||
$e->getMessage()
|
||||
]
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App\State;
|
||||
namespace Magento\Framework\TestFramework\ApplicationStateComparator;
|
||||
|
||||
/**
|
||||
* Immutable recursive data structure that holds copy of properties from collected objects. Created by Collector.
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App\State;
|
||||
namespace Magento\Framework\TestFramework\ApplicationStateComparator;
|
||||
|
||||
/**
|
||||
* Returned by Collector
|
||||
+19
-12
@@ -5,13 +5,16 @@
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App\State;
|
||||
namespace Magento\Framework\TestFramework\ApplicationStateComparator;
|
||||
|
||||
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
|
||||
use Magento\Framework\ObjectManagerInterface;
|
||||
use Magento\Framework\TestFramework\ApplicationStateComparator\ObjectManagerInterface as StateObjectManagerInterface;
|
||||
|
||||
/**
|
||||
* Collects shared objects from ObjectManager and copies properties for later comparison
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class Collector
|
||||
{
|
||||
@@ -30,8 +33,8 @@ class Collector
|
||||
SkipListAndFilterList $skipListAndFilterList
|
||||
) {
|
||||
$this->skipListFromConstructed =
|
||||
$skipListAndFilterList->getSkipList('', CompareType::CompareConstructedAgainstCurrent);
|
||||
$this->skipListBetweenRequests = $skipListAndFilterList->getSkipList('', CompareType::CompareBetweenRequests);
|
||||
$skipListAndFilterList->getSkipList('', CompareType::COMPARE_CONSTRUCTED_AGAINST_CURRENT);
|
||||
$this->skipListBetweenRequests = $skipListAndFilterList->getSkipList('', CompareType::COMPARE_BETWEEN_REQUESTS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,16 +86,18 @@ class Collector
|
||||
/**
|
||||
* Gets shared objects from ObjectManager using reflection and copies properties that are objects
|
||||
*
|
||||
* @param ShouldResetState $shouldResetState
|
||||
* @param string $shouldResetState
|
||||
* @return CollectedObject[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getSharedObjects(string $shouldResetState): array
|
||||
{
|
||||
if ($this->objectManager instanceof ObjectManager) {
|
||||
if ($this->objectManager instanceof ObjectManagerInterface) {
|
||||
$sharedInstances = $this->objectManager->getSharedInstances();
|
||||
} else {
|
||||
$obj = new \ReflectionObject($this->objectManager);
|
||||
if (!$obj->hasProperty('_sharedInstances')) {
|
||||
// phpcs:ignore Magento2.Exceptions.DirectThrow
|
||||
throw new \Exception('Cannot get shared objects from ' . get_class($this->objectManager));
|
||||
}
|
||||
$property = $obj->getProperty('_sharedInstances');
|
||||
@@ -104,7 +109,7 @@ class Collector
|
||||
if (array_key_exists($serviceName, $sharedObjects)) {
|
||||
continue;
|
||||
}
|
||||
if (ShouldResetState::DoResetState == $shouldResetState &&
|
||||
if (ShouldResetState::DO_RESET_STATE == $shouldResetState &&
|
||||
($object instanceof ResetAfterRequestInterface)) {
|
||||
$object->_resetState();
|
||||
}
|
||||
@@ -112,7 +117,7 @@ class Collector
|
||||
continue;
|
||||
}
|
||||
$sharedObjects[$serviceName] =
|
||||
$this->getPropertiesFromObject($object, CompareType::CompareBetweenRequests);
|
||||
$this->getPropertiesFromObject($object, CompareType::COMPARE_BETWEEN_REQUESTS);
|
||||
}
|
||||
return $sharedObjects;
|
||||
}
|
||||
@@ -123,12 +128,14 @@ class Collector
|
||||
* This also calls _resetState on any ResetAfterRequestInterface
|
||||
*
|
||||
* @return CollectedObjectConstructedAndCurrent[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getPropertiesConstructedAndCurrent(): array
|
||||
{
|
||||
/** @var ObjectManager $objectManager */
|
||||
$objectManager = $this->objectManager;
|
||||
if (!($objectManager instanceof ObjectManager)) {
|
||||
if (!($objectManager instanceof StateObjectManagerInterface)) {
|
||||
// phpcs:ignore Magento2.Exceptions.DirectThrow
|
||||
throw new \Exception("Not the correct type of ObjectManager");
|
||||
}
|
||||
// Calling _resetState helps us avoid adding skip/filter for these classes.
|
||||
@@ -138,7 +145,7 @@ class Collector
|
||||
$objects[] = new CollectedObjectConstructedAndCurrent(
|
||||
$object,
|
||||
$propertiesBefore,
|
||||
$this->getPropertiesFromObject($object, CompareType::CompareConstructedAgainstCurrent),
|
||||
$this->getPropertiesFromObject($object, CompareType::COMPARE_CONSTRUCTED_AGAINST_CURRENT),
|
||||
);
|
||||
}
|
||||
return $objects;
|
||||
@@ -157,15 +164,15 @@ class Collector
|
||||
public function getPropertiesFromObject(
|
||||
object $object,
|
||||
string $compareType,
|
||||
int $recursionLevel = 1,
|
||||
int $recursionLevel = 0,
|
||||
): CollectedObject {
|
||||
$className = get_class($object);
|
||||
$skipList = $compareType == CompareType::CompareBetweenRequests ?
|
||||
$skipList = $compareType == CompareType::COMPARE_BETWEEN_REQUESTS ?
|
||||
$this->skipListBetweenRequests : $this->skipListFromConstructed ;
|
||||
if (array_key_exists($className, $skipList)) {
|
||||
return CollectedObject::getSkippedObject();
|
||||
}
|
||||
if ($this->objectManager instanceof ObjectManager) {
|
||||
if ($this->objectManager instanceof StateObjectManagerInterface) {
|
||||
$serviceName = array_search($object, $this->objectManager->getSharedInstances(), true);
|
||||
if ($serviceName && array_key_exists($serviceName, $skipList)) {
|
||||
return CollectedObject::getSkippedObject();
|
||||
+21
-14
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App\State;
|
||||
namespace Magento\Framework\TestFramework\ApplicationStateComparator;
|
||||
|
||||
use Magento\Framework\ObjectManager\NoninterceptableInterface;
|
||||
|
||||
@@ -41,7 +41,7 @@ class Comparator
|
||||
public function rememberObjectsStateBefore(bool $firstRequest): void
|
||||
{
|
||||
if ($firstRequest) {
|
||||
$this->objectsStateBefore = $this->collector->getSharedObjects(ShouldResetState::DoNotResetState);
|
||||
$this->objectsStateBefore = $this->collector->getSharedObjects(ShouldResetState::DO_NOT_RESET_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class Comparator
|
||||
*/
|
||||
public function rememberObjectsStateAfter(bool $firstRequest): void
|
||||
{
|
||||
$this->objectsStateAfter = $this->collector->getSharedObjects(ShouldResetState::DoResetState);
|
||||
$this->objectsStateAfter = $this->collector->getSharedObjects(ShouldResetState::DO_RESET_STATE);
|
||||
if ($firstRequest) {
|
||||
// on the end of first request add objects to init object state pool
|
||||
$this->objectsStateBefore = array_merge($this->objectsStateAfter, $this->objectsStateBefore);
|
||||
@@ -71,7 +71,7 @@ class Comparator
|
||||
public function compareBetweenRequests(string $operationName): array
|
||||
{
|
||||
$compareResults = [];
|
||||
$skipList = $this->skipListAndFilterList->getSkipList($operationName, CompareType::CompareBetweenRequests);
|
||||
$skipList = $this->skipListAndFilterList->getSkipList($operationName, CompareType::COMPARE_BETWEEN_REQUESTS);
|
||||
foreach ($this->objectsStateAfter as $serviceName => $afterCollectedObject) {
|
||||
if (array_key_exists($serviceName, $skipList)) {
|
||||
continue;
|
||||
@@ -101,7 +101,7 @@ class Comparator
|
||||
{
|
||||
$compareResults = [];
|
||||
$skipList = $this->skipListAndFilterList
|
||||
->getSkipList($operationName, CompareType::CompareConstructedAgainstCurrent);
|
||||
->getSkipList($operationName, CompareType::COMPARE_CONSTRUCTED_AGAINST_CURRENT);
|
||||
foreach ($this->collector->getPropertiesConstructedAndCurrent() as $objectAndProperties) {
|
||||
$object = $objectAndProperties->getObject();
|
||||
$constructedObject = $objectAndProperties->getConstructedCollected();
|
||||
@@ -179,16 +179,21 @@ class Comparator
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($objectState) {
|
||||
return [
|
||||
'objectClassBefore' => $before->getClassName(),
|
||||
'objectClassAfter' => $after->getClassName(),
|
||||
'properties' => $objectState,
|
||||
'objectIdBefore' => $before->getObjectId(),
|
||||
'objectIdAfter' => $after->getObjectId(),
|
||||
];
|
||||
if (!$objectState) {
|
||||
return [];
|
||||
}
|
||||
return [];
|
||||
$returnValue = [
|
||||
'objectClassBefore' => $before->getClassName(),
|
||||
'properties' => $objectState,
|
||||
];
|
||||
if ($returnValue['objectClassBefore'] !== $after->getClassName()) {
|
||||
$returnValue['objectClassAfter'] = $after->getClassName();
|
||||
}
|
||||
if ($before->getObjectId() != $after->getObjectId()) {
|
||||
$returnValue['objectIdBefore'] = $before->getObjectId();
|
||||
$returnValue['objectIdAfter'] = $after->getObjectId();
|
||||
}
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,6 +231,7 @@ class Comparator
|
||||
* @param array $skipList
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function checkValues(mixed $before, mixed $after, array $skipList): array
|
||||
{
|
||||
@@ -282,6 +288,7 @@ class Comparator
|
||||
$skipList,
|
||||
);
|
||||
}
|
||||
// phpcs:ignore Magento2.Exceptions.DirectThrow
|
||||
throw new \Exception("Unexpected object in checkValues()");
|
||||
}
|
||||
return [];
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\Framework\TestFramework\ApplicationStateComparator;
|
||||
|
||||
/**
|
||||
* What type of comparison
|
||||
*/
|
||||
class CompareType
|
||||
{
|
||||
public const COMPARE_BETWEEN_REQUESTS = "CompareBetweenRequests";
|
||||
public const COMPARE_CONSTRUCTED_AGAINST_CURRENT = "CompareConstructedAgainstCurrent";
|
||||
}
|
||||
+4
-4
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App\State;
|
||||
namespace Magento\Framework\TestFramework\ApplicationStateComparator;
|
||||
|
||||
use Magento\Framework\ObjectManager\Factory\Dynamic\Developer;
|
||||
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
|
||||
@@ -43,7 +43,7 @@ class DynamicFactoryDecorator extends Developer implements ResetAfterRequestInte
|
||||
$this->objectManager = $objectManager;
|
||||
$this->weakMap = new WeakMap();
|
||||
$skipListAndFilterList = new SkipListAndFilterList;
|
||||
$this->skipList = $skipListAndFilterList->getSkipList('', CompareType::CompareConstructedAgainstCurrent);
|
||||
$this->skipList = $skipListAndFilterList->getSkipList('', CompareType::COMPARE_CONSTRUCTED_AGAINST_CURRENT);
|
||||
$this->collector = new Collector($this->objectManager, $skipListAndFilterList);
|
||||
$this->objectManager->addSharedInstance($skipListAndFilterList, SkipListAndFilterList::class);
|
||||
$this->objectManager->addSharedInstance($this->collector, Collector::class);
|
||||
@@ -57,7 +57,7 @@ class DynamicFactoryDecorator extends Developer implements ResetAfterRequestInte
|
||||
$object = parent::create($type, $arguments);
|
||||
if (!array_key_exists(get_class($object), $this->skipList)) {
|
||||
$this->weakMap[$object] =
|
||||
$this->collector->getPropertiesFromObject($object, CompareType::CompareConstructedAgainstCurrent);
|
||||
$this->collector->getPropertiesFromObject($object, CompareType::COMPARE_CONSTRUCTED_AGAINST_CURRENT);
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
@@ -102,7 +102,7 @@ class DynamicFactoryDecorator extends Developer implements ResetAfterRequestInte
|
||||
/**
|
||||
* Returns the WeakMap that stores the CollectedObject
|
||||
*
|
||||
* @return WeakMap
|
||||
* @return WeakMap with CollectedObject as values
|
||||
*/
|
||||
public function getWeakMap() : WeakMap
|
||||
{
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\Framework\TestFramework\ApplicationStateComparator;
|
||||
|
||||
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
|
||||
use Magento\TestFramework\ObjectManager as TestFrameworkObjectManager;
|
||||
use Weakmap;
|
||||
|
||||
/**
|
||||
* ObjectManager decorator used by GraphQlStateTest for resetting objects and getting initial properties from objects
|
||||
*/
|
||||
class ObjectManager extends TestFrameworkObjectManager implements ObjectManagerInterface
|
||||
{
|
||||
//phpcs:disable Magento2.PHP.LiteralNamespaces
|
||||
/**
|
||||
* @var array|string[]
|
||||
*/
|
||||
private array $bootstrappedObjects = [
|
||||
// Note: These are after $objectManager = $this->_factory->create($overriddenParams);
|
||||
'Magento\Framework\App\DeploymentConfig',
|
||||
'Magento\Framework\App\Filesystem\DirectoryList',
|
||||
'Magento\Framework\Filesystem\DirectoryList',
|
||||
'Magento\Framework\Filesystem\DriverPool',
|
||||
'Magento\Framework\ObjectManager\RelationsInterface',
|
||||
'Magento\Framework\Interception\DefinitionInterface',
|
||||
'Magento\Framework\ObjectManager\ConfigInterface',
|
||||
'Magento\Framework\Interception\ObjectManager\ConfigInterface',
|
||||
'Magento\Framework\ObjectManager\DefinitionInterface',
|
||||
'Magento\Framework\Stdlib\BooleanUtils',
|
||||
'Magento\Framework\ObjectManager\Config\Mapper\Dom',
|
||||
'Magento\Framework\ObjectManager\ConfigLoaderInterface',
|
||||
'Magento\TestFramework\ObjectManager\Config',
|
||||
'Magento\Framework\ObjectManagerInterface',
|
||||
'Magento\RemoteStorage\Model\Config',
|
||||
'Magento\RemoteStorage\Driver\Adapter\MetadataProviderInterfaceFactory',
|
||||
'Magento\RemoteStorage\Driver\Adapter\Cache\CacheInterfaceFactory',
|
||||
'Magento\RemoteStorage\Driver\Adapter\CachedAdapterInterfaceFactory',
|
||||
'Magento\Framework\App\Cache\Proxy',
|
||||
'Aws\Credentials\CredentialsFactory',
|
||||
'Magento\Framework\Serialize\Serializer\Json',
|
||||
'Magento\AwsS3\Driver\CredentialsCache',
|
||||
'Magento\AwsS3\Driver\CachedCredentialsProvider',
|
||||
'Magento\AwsS3\Driver\AwsS3Factory',
|
||||
'Magento\RemoteStorage\Driver\DriverFactoryPool',
|
||||
'Magento\RemoteStorage\Driver\DriverPool',
|
||||
'remoteReadFactory',
|
||||
'Magento\RemoteStorage\Model\Filesystem\Directory\WriteFactory',
|
||||
'customRemoteFilesystem',
|
||||
'Magento\Framework\App\ResourceConnection\Proxy',
|
||||
'Magento\Framework\App\Cache\Frontend\Factory',
|
||||
'Magento\Framework\App\Cache\Frontend\Pool',
|
||||
'Magento\Framework\App\Cache\Type\FrontendPool',
|
||||
'Magento\Framework\App\Cache\Type\Config',
|
||||
'Magento\Framework\ObjectManager\Config\Reader\DomFactory',
|
||||
'Magento\Framework\Serialize\Serializer\Serialize',
|
||||
'Magento\Framework\App\ObjectManager\ConfigLoader',
|
||||
// Note: These were added by addSharedInstance
|
||||
'Magento\Framework\App\Filesystem\DirectoryList',
|
||||
'Magento\Framework\Filesystem\DirectoryList',
|
||||
'Magento\Framework\Filesystem',
|
||||
'Magento\Framework\Logger\LoggerProxy',
|
||||
'Magento\TestFramework\ErrorLog\Logger',
|
||||
'Magento\SalesSequence\Model\Builder',
|
||||
'Magento\Framework\App\Filesystem\DirectoryList',
|
||||
'Magento\Framework\Filesystem\DirectoryList',
|
||||
'Magento\Framework\App\DeploymentConfig',
|
||||
'Magento\Framework\ObjectManager\ConfigLoaderInterface',
|
||||
'Magento\Framework\Filesystem',
|
||||
'Magento\Framework\Logger\LoggerProxy',
|
||||
'Magento\TestFramework\ErrorLog\Logger',
|
||||
'Magento\SalesSequence\Model\Builder',
|
||||
'Magento\Framework\App\Filesystem\DirectoryList',
|
||||
'Magento\Framework\Filesystem\DirectoryList',
|
||||
'Magento\Framework\App\DeploymentConfig',
|
||||
'Magento\Framework\ObjectManager\ConfigLoaderInterface',
|
||||
'Magento\Framework\Filesystem',
|
||||
'Magento\Framework\Logger\LoggerProxy',
|
||||
'Magento\TestFramework\ErrorLog\Logger',
|
||||
'Magento\SalesSequence\Model\Builder',
|
||||
'Magento\Framework\TestFramework\ApplicationStateComparator\SkipListAndFilterList',
|
||||
'Magento\Framework\TestFramework\ApplicationStateComparator\Collector',
|
||||
'Magento\Framework\App\Filesystem\DirectoryList',
|
||||
'Magento\Framework\Filesystem\DirectoryList',
|
||||
'Magento\Framework\App\DeploymentConfig',
|
||||
'Magento\Framework\ObjectManager\ConfigLoaderInterface',
|
||||
'Magento\Framework\Filesystem',
|
||||
'Magento\Framework\Logger\LoggerProxy',
|
||||
'Magento\TestFramework\ErrorLog\Logger',
|
||||
'Magento\SalesSequence\Model\Builder',
|
||||
];
|
||||
|
||||
/**
|
||||
* Constructs this instance by copying test framework's ObjectManager
|
||||
*
|
||||
* @param TestFrameworkObjectManager $testFrameworkObjectManager
|
||||
*/
|
||||
public function __construct(TestFrameworkObjectManager $testFrameworkObjectManager)
|
||||
{
|
||||
/* Note: PHP doesn't have copy constructors, so we have to use get_object_vars,
|
||||
* but luckily all the properties in the superclass are protected. */
|
||||
$properties = get_object_vars($testFrameworkObjectManager);
|
||||
foreach ($properties as $key => $value) {
|
||||
if ($key === '_sharedInstances') {
|
||||
foreach ($value as $class => $instance) {
|
||||
if (in_array($class, $this->bootstrappedObjects)) {
|
||||
$this->_sharedInstances[$class] = $instance;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
|
||||
}
|
||||
$this->_sharedInstances['Magento\Framework\ObjectManagerInterface'] = $this;
|
||||
$this->_sharedInstances['Magento\Framework\App\ObjectManager'] = $this;
|
||||
$this->_factory = new DynamicFactoryDecorator($this->_factory, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the WeakMap used by DynamicFactoryDecorator
|
||||
*
|
||||
* @return WeakMap with CollectedObject as values
|
||||
*/
|
||||
public function getWeakMap() : WeakMap
|
||||
{
|
||||
return $this->_factory->getWeakMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns shared instances
|
||||
*
|
||||
* @return object[]
|
||||
*/
|
||||
public function getSharedInstances() : array
|
||||
{
|
||||
return $this->_sharedInstances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all factory objects that implement ResetAfterRequestInterface
|
||||
*/
|
||||
public function resetStateWeakMapObjects() : void
|
||||
{
|
||||
$this->_factory->_resetState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all objects sharing state & implementing ResetAfterRequestInterface
|
||||
*/
|
||||
public function resetStateSharedInstances() : void
|
||||
{
|
||||
/** @var object $object */
|
||||
foreach ($this->_sharedInstances as $object) {
|
||||
if ($object instanceof ResetAfterRequestInterface) {
|
||||
$object->_resetState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\Framework\TestFramework\ApplicationStateComparator;
|
||||
|
||||
use Magento\Framework\ObjectManagerInterface as FrameworkObjectManagerInterface;
|
||||
use Weakmap;
|
||||
|
||||
/**
|
||||
* Interface for ObjectManager that has additional methods used by Collector for comparing state
|
||||
*/
|
||||
interface ObjectManagerInterface extends FrameworkObjectManagerInterface
|
||||
{
|
||||
/**
|
||||
* Returns the WeakMap with CollectedObject as values
|
||||
*
|
||||
* @return WeakMap with CollectedObject as values
|
||||
*/
|
||||
public function getWeakMap() : WeakMap;
|
||||
|
||||
/**
|
||||
* Returns shared instances
|
||||
*
|
||||
* @return object[]
|
||||
*/
|
||||
public function getSharedInstances() : array;
|
||||
|
||||
/**
|
||||
* Resets all factory objects that implement ResetAfterRequestInterface
|
||||
*/
|
||||
public function resetStateWeakMapObjects() : void;
|
||||
|
||||
/**
|
||||
* Resets all objects sharing state & implementing ResetAfterRequestInterface
|
||||
*/
|
||||
public function resetStateSharedInstances() : void;
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright © Magento, Inc. All rights reserved.
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\Framework\TestFramework\ApplicationStateComparator;
|
||||
|
||||
class ShouldResetState
|
||||
{
|
||||
public const DO_RESET_STATE = "DoResetState";
|
||||
public const DO_NOT_RESET_STATE = "DoNotResetState";
|
||||
}
|
||||
+11
-5
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\GraphQl\App\State;
|
||||
namespace Magento\Framework\TestFramework\ApplicationStateComparator;
|
||||
|
||||
/**
|
||||
* Skip List and Filter List for collecting and comparing objects created by ObjectManager
|
||||
@@ -27,6 +27,9 @@ class SkipListAndFilterList
|
||||
*/
|
||||
private ?array $filterList = null;
|
||||
|
||||
private const FIXTURE_PATH =
|
||||
"/dev/tests/integration/framework/Magento/TestFramework/ApplicationStateComparator/_files";
|
||||
|
||||
/**
|
||||
* Filters properties by the list of property filters
|
||||
*
|
||||
@@ -43,23 +46,26 @@ class SkipListAndFilterList
|
||||
* Gets skipList, loading it if needed
|
||||
*
|
||||
* @param string $operationName
|
||||
* @param CompareType $compareType
|
||||
* @param string $compareType
|
||||
* @return array
|
||||
*/
|
||||
public function getSkipList(string $operationName, string $compareType): array
|
||||
{
|
||||
if ($this->skipList === null) {
|
||||
$skipListList = [];
|
||||
foreach (glob(__DIR__ . '/../../_files/state-skip-list*.php') as $skipListFile) {
|
||||
foreach (glob(BP . self::FIXTURE_PATH . '/state-skip-list*.php') as $skipListFile) {
|
||||
$skipListList[] = include($skipListFile);
|
||||
}
|
||||
$this->skipList = array_merge_recursive(...$skipListList);
|
||||
}
|
||||
if ('*' === $operationName) {
|
||||
return array_merge(...array_values($this->skipList));
|
||||
}
|
||||
$skipLists = [$this->skipList['*']];
|
||||
if (array_key_exists($operationName, $this->skipList)) {
|
||||
$skipLists[] = $this->skipList[$operationName];
|
||||
}
|
||||
if (CompareType::CompareConstructedAgainstCurrent == $compareType) {
|
||||
if (CompareType::COMPARE_CONSTRUCTED_AGAINST_CURRENT == $compareType) {
|
||||
if (array_key_exists($operationName . '-fromConstructed', $this->skipList)) {
|
||||
$skipLists[] = $this->skipList[$operationName . '-fromConstructed'];
|
||||
}
|
||||
@@ -79,7 +85,7 @@ class SkipListAndFilterList
|
||||
{
|
||||
if ($this->filterList === null) {
|
||||
$filterListList = [];
|
||||
foreach (glob(__DIR__ . '/../../_files/state-filter-list*.php') as $filterListFile) {
|
||||
foreach (glob(BP . self::FIXTURE_PATH . '/state-filter-list*.php') as $filterListFile) {
|
||||
$filterListList[] = include($filterListFile);
|
||||
}
|
||||
$this->filterList = array_merge_recursive(...$filterListList);
|
||||
Vendored
+3
-3
@@ -1,14 +1,14 @@
|
||||
/*!
|
||||
* Chart.js v4.3.0
|
||||
* Chart.js v4.4.0
|
||||
* https://www.chartjs.org
|
||||
* (c) 2023 Chart.js Contributors
|
||||
* Released under the MIT License
|
||||
*/
|
||||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chart=e()}(this,(function(){"use strict";var t=Object.freeze({__proto__:null,get Colors(){return Ko},get Decimation(){return Jo},get Filler(){return pa},get Legend(){return _a},get SubTitle(){return wa},get Title(){return va},get Tooltip(){return Va}});function e(){}const i=(()=>{let t=0;return()=>t++})();function s(t){return null==t}function n(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.slice(0,7)&&"Array]"===e.slice(-6)}function o(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}function a(t){return("number"==typeof t||t instanceof Number)&&isFinite(+t)}function r(t,e){return a(t)?t:e}function l(t,e){return void 0===t?e:t}const h=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:+t/e,c=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function d(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function u(t,e,i,s){let a,r,l;if(n(t))if(r=t.length,s)for(a=r-1;a>=0;a--)e.call(i,t[a],a);else for(a=0;a<r;a++)e.call(i,t[a],a);else if(o(t))for(l=Object.keys(t),r=l.length,a=0;a<r;a++)e.call(i,t[l[a]],l[a])}function f(t,e){let i,s,n,o;if(!t||!e||t.length!==e.length)return!1;for(i=0,s=t.length;i<s;++i)if(n=t[i],o=e[i],n.datasetIndex!==o.datasetIndex||n.index!==o.index)return!1;return!0}function g(t){if(n(t))return t.map(g);if(o(t)){const e=Object.create(null),i=Object.keys(t),s=i.length;let n=0;for(;n<s;++n)e[i[n]]=g(t[i[n]]);return e}return t}function p(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}function m(t,e,i,s){if(!p(t))return;const n=e[t],a=i[t];o(n)&&o(a)?b(n,a,s):e[t]=g(a)}function b(t,e,i){const s=n(e)?e:[e],a=s.length;if(!o(t))return t;const r=(i=i||{}).merger||m;let l;for(let e=0;e<a;++e){if(l=s[e],!o(l))continue;const n=Object.keys(l);for(let e=0,s=n.length;e<s;++e)r(n[e],t,l,i)}return t}function x(t,e){return b(t,e,{merger:_})}function _(t,e,i){if(!p(t))return;const s=e[t],n=i[t];o(s)&&o(n)?x(s,n):Object.prototype.hasOwnProperty.call(e,t)||(e[t]=g(n))}const y={"":t=>t,x:t=>t.x,y:t=>t.y};function v(t){const e=t.split("."),i=[];let s="";for(const t of e)s+=t,s.endsWith("\\")?s=s.slice(0,-1)+".":(i.push(s),s="");return i}function M(t,e){const i=y[e]||(y[e]=function(t){const e=v(t);return t=>{for(const i of e){if(""===i)break;t=t&&t[i]}return t}}(e));return i(t)}function w(t){return t.charAt(0).toUpperCase()+t.slice(1)}const k=t=>void 0!==t,S=t=>"function"==typeof t,P=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function D(t){return"mouseup"===t.type||"click"===t.type||"contextmenu"===t.type}const C=Math.PI,O=2*C,A=O+C,T=Number.POSITIVE_INFINITY,L=C/180,E=C/2,R=C/4,I=2*C/3,z=Math.log10,F=Math.sign;function V(t,e,i){return Math.abs(t-e)<i}function B(t){const e=Math.round(t);t=V(t,e,t/1e3)?e:t;const i=Math.pow(10,Math.floor(z(t))),s=t/i;return(s<=1?1:s<=2?2:s<=5?5:10)*i}function N(t){const e=[],i=Math.sqrt(t);let s;for(s=1;s<i;s++)t%s==0&&(e.push(s),e.push(t/s));return i===(0|i)&&e.push(i),e.sort(((t,e)=>t-e)).pop(),e}function W(t){return!isNaN(parseFloat(t))&&isFinite(t)}function H(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function j(t,e,i){let s,n,o;for(s=0,n=t.length;s<n;s++)o=t[s][i],isNaN(o)||(e.min=Math.min(e.min,o),e.max=Math.max(e.max,o))}function $(t){return t*(C/180)}function Y(t){return t*(180/C)}function U(t){if(!a(t))return;let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}function X(t,e){const i=e.x-t.x,s=e.y-t.y,n=Math.sqrt(i*i+s*s);let o=Math.atan2(s,i);return o<-.5*C&&(o+=O),{angle:o,distance:n}}function q(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function K(t,e){return(t-e+A)%O-C}function G(t){return(t%O+O)%O}function Z(t,e,i,s){const n=G(t),o=G(e),a=G(i),r=G(o-n),l=G(a-n),h=G(n-o),c=G(n-a);return n===o||n===a||s&&o===a||r>l&&h<c}function J(t,e,i){return Math.max(e,Math.min(i,t))}function Q(t){return J(t,-32768,32767)}function tt(t,e,i,s=1e-6){return t>=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function et(t,e,i){i=i||(i=>t[i]<e);let s,n=t.length-1,o=0;for(;n-o>1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const it=(t,e,i,s)=>et(t,i,s?s=>{const n=t[s][e];return n<i||n===i&&t[s+1][e]===i}:s=>t[s][e]<i),st=(t,e,i)=>et(t,i,(s=>t[s][e]>=i));function nt(t,e,i){let s=0,n=t.length;for(;s<n&&t[s]<e;)s++;for(;n>s&&t[n-1]>i;)n--;return s>0||n<t.length?t.slice(s,n):t}const ot=["push","pop","shift","splice","unshift"];function at(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),ot.forEach((e=>{const i="_onData"+w(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),n}})})))}function rt(t,e){Line truncated
|
||||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chart=e()}(this,(function(){"use strict";var t=Object.freeze({__proto__:null,get Colors(){return Go},get Decimation(){return Qo},get Filler(){return ma},get Legend(){return ya},get SubTitle(){return ka},get Title(){return Ma},get Tooltip(){return Ba}});function e(){}const i=(()=>{let t=0;return()=>t++})();function s(t){return null==t}function n(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.slice(0,7)&&"Array]"===e.slice(-6)}function o(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}function a(t){return("number"==typeof t||t instanceof Number)&&isFinite(+t)}function r(t,e){return a(t)?t:e}function l(t,e){return void 0===t?e:t}const h=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:+t/e,c=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function d(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function u(t,e,i,s){let a,r,l;if(n(t))if(r=t.length,s)for(a=r-1;a>=0;a--)e.call(i,t[a],a);else for(a=0;a<r;a++)e.call(i,t[a],a);else if(o(t))for(l=Object.keys(t),r=l.length,a=0;a<r;a++)e.call(i,t[l[a]],l[a])}function f(t,e){let i,s,n,o;if(!t||!e||t.length!==e.length)return!1;for(i=0,s=t.length;i<s;++i)if(n=t[i],o=e[i],n.datasetIndex!==o.datasetIndex||n.index!==o.index)return!1;return!0}function g(t){if(n(t))return t.map(g);if(o(t)){const e=Object.create(null),i=Object.keys(t),s=i.length;let n=0;for(;n<s;++n)e[i[n]]=g(t[i[n]]);return e}return t}function p(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}function m(t,e,i,s){if(!p(t))return;const n=e[t],a=i[t];o(n)&&o(a)?b(n,a,s):e[t]=g(a)}function b(t,e,i){const s=n(e)?e:[e],a=s.length;if(!o(t))return t;const r=(i=i||{}).merger||m;let l;for(let e=0;e<a;++e){if(l=s[e],!o(l))continue;const n=Object.keys(l);for(let e=0,s=n.length;e<s;++e)r(n[e],t,l,i)}return t}function x(t,e){return b(t,e,{merger:_})}function _(t,e,i){if(!p(t))return;const s=e[t],n=i[t];o(s)&&o(n)?x(s,n):Object.prototype.hasOwnProperty.call(e,t)||(e[t]=g(n))}const y={"":t=>t,x:t=>t.x,y:t=>t.y};function v(t){const e=t.split("."),i=[];let s="";for(const t of e)s+=t,s.endsWith("\\")?s=s.slice(0,-1)+".":(i.push(s),s="");return i}function M(t,e){const i=y[e]||(y[e]=function(t){const e=v(t);return t=>{for(const i of e){if(""===i)break;t=t&&t[i]}return t}}(e));return i(t)}function w(t){return t.charAt(0).toUpperCase()+t.slice(1)}const k=t=>void 0!==t,S=t=>"function"==typeof t,P=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function D(t){return"mouseup"===t.type||"click"===t.type||"contextmenu"===t.type}const C=Math.PI,O=2*C,A=O+C,T=Number.POSITIVE_INFINITY,L=C/180,E=C/2,R=C/4,I=2*C/3,z=Math.log10,F=Math.sign;function V(t,e,i){return Math.abs(t-e)<i}function B(t){const e=Math.round(t);t=V(t,e,t/1e3)?e:t;const i=Math.pow(10,Math.floor(z(t))),s=t/i;return(s<=1?1:s<=2?2:s<=5?5:10)*i}function W(t){const e=[],i=Math.sqrt(t);let s;for(s=1;s<i;s++)t%s==0&&(e.push(s),e.push(t/s));return i===(0|i)&&e.push(i),e.sort(((t,e)=>t-e)).pop(),e}function N(t){return!isNaN(parseFloat(t))&&isFinite(t)}function H(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function j(t,e,i){let s,n,o;for(s=0,n=t.length;s<n;s++)o=t[s][i],isNaN(o)||(e.min=Math.min(e.min,o),e.max=Math.max(e.max,o))}function $(t){return t*(C/180)}function Y(t){return t*(180/C)}function U(t){if(!a(t))return;let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}function X(t,e){const i=e.x-t.x,s=e.y-t.y,n=Math.sqrt(i*i+s*s);let o=Math.atan2(s,i);return o<-.5*C&&(o+=O),{angle:o,distance:n}}function q(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function K(t,e){return(t-e+A)%O-C}function G(t){return(t%O+O)%O}function Z(t,e,i,s){const n=G(t),o=G(e),a=G(i),r=G(o-n),l=G(a-n),h=G(n-o),c=G(n-a);return n===o||n===a||s&&o===a||r>l&&h<c}function J(t,e,i){return Math.max(e,Math.min(i,t))}function Q(t){return J(t,-32768,32767)}function tt(t,e,i,s=1e-6){return t>=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function et(t,e,i){i=i||(i=>t[i]<e);let s,n=t.length-1,o=0;for(;n-o>1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const it=(t,e,i,s)=>et(t,i,s?s=>{const n=t[s][e];return n<i||n===i&&t[s+1][e]===i}:s=>t[s][e]<i),st=(t,e,i)=>et(t,i,(s=>t[s][e]>=i));function nt(t,e,i){let s=0,n=t.length;for(;s<n&&t[s]<e;)s++;for(;n>s&&t[n-1]>i;)n--;return s>0||n<t.length?t.slice(s,n):t}const ot=["push","pop","shift","splice","unshift"];function at(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),ot.forEach((e=>{const i="_onData"+w(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),n}})})))}function rt(t,e){Line truncated
|
||||
/*!
|
||||
* @kurkle/color v0.3.2
|
||||
* https://github.com/kurkle/color#readme
|
||||
* (c) 2023 Jukka Kurkela
|
||||
* Released under the MIT License
|
||||
*/function _t(t){return t+.5|0}const yt=(t,e,i)=>Math.max(Math.min(t,i),e);function vt(t){return yt(_t(2.55*t),0,255)}function Mt(t){return yt(_t(255*t),0,255)}function wt(t){return yt(_t(t/2.55)/100,0,1)}function kt(t){return yt(_t(100*t),0,100)}const St={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},Pt=[..."0123456789ABCDEF"],Dt=t=>Pt[15&t],Ct=t=>Pt[(240&t)>>4]+Pt[15&t],Ot=t=>(240&t)>>4==(15&t);function At(t){var e=(t=>Ot(t.r)&&Ot(t.g)&&Ot(t.b)&&Ot(t.a))(t)?Dt:Ct;return t?"#"+e(t.r)+e(t.g)+e(t.b)+((t,e)=>t<255?e(t):"")(t.a,e):void 0}const Tt=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function Lt(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function Et(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function Rt(t,e,i){const s=Lt(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function It(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=function(t,e,i,s,n){return t===n?(e-i)/s+(e<i?6:0):e===n?(i-t)/s+2:(t-e)/s+4}(e,i,s,h,n),r=60*r+.5),[0|r,l||0,a]}function zt(t,e,i,s){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,s)).map(Mt)}function Ft(t,e,i){return zt(Lt,t,e,i)}function Vt(t){return(t%360+360)%360}function Bt(t){const e=Tt.exec(t);let i,s=255;if(!e)return;e[5]!==i&&(s=e[6]?vt(+e[5]):Mt(+e[5]));const n=Vt(+e[2]),o=+e[3]/100,a=+e[4]/100;return i="hwb"===e[1]?function(t,e,i){return zt(Rt,t,e,i)}(n,o,a):"hsv"===e[1]?function(t,e,i){return zt(Et,t,e,i)}(n,o,a):Ft(n,o,a),{r:i[0],g:i[1],b:i[2],a:s}}const Nt={x:"dark",Z:"light",Y:"re",X:"blu",W:"gr",V:"medium",U:"slate",A:"ee",T:"ol",S:"or",B:"ra",C:"lateg",D:"ights",R:"in",Q:"turquois",E:"hi",P:"ro",O:"al",N:"le",M:"de",L:"yello",F:"en",K:"ch",G:"arks",H:"ea",I:"ightg",J:"wh"},Wt={OiceXe:"f0f8ff",antiquewEte:"faebd7",aqua:"ffff",aquamarRe:"7fffd4",azuY:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"0",blanKedOmond:"ffebcd",Xe:"ff",XeviTet:"8a2be2",bPwn:"a52a2a",burlywood:"deb887",caMtXe:"5f9ea0",KartYuse:"7fff00",KocTate:"d2691e",cSO:"ff7f50",cSnflowerXe:"6495ed",cSnsilk:"fff8dc",crimson:"dc143c",cyan:"ffff",xXe:"8b",xcyan:"8b8b",xgTMnPd:"b8860b",xWay:"a9a9a9",xgYF:"6400",xgYy:"a9a9a9",xkhaki:"bdb76b",xmagFta:"8b008b",xTivegYF:"556b2f",xSange:"ff8c00",xScEd:"9932cc",xYd:"8b0000",xsOmon:"e9967a",xsHgYF:"8fbc8f",xUXe:"483d8b",xUWay:"2f4f4f",xUgYy:"2f4f4f",xQe:"ced1",xviTet:"9400d3",dAppRk:"ff1493",dApskyXe:"bfff",dimWay:"696969",dimgYy:"696969",dodgerXe:"1e90ff",fiYbrick:"b22222",flSOwEte:"fffaf0",foYstWAn:"228b22",fuKsia:"ff00ff",gaRsbSo:"dcdcdc",ghostwEte:"f8f8ff",gTd:"ffd700",gTMnPd:"daa520",Way:"808080",gYF:"8000",gYFLw:"adff2f",gYy:"808080",honeyMw:"f0fff0",hotpRk:"ff69b4",RdianYd:"cd5c5c",Rdigo:"4b0082",ivSy:"fffff0",khaki:"f0e68c",lavFMr:"e6e6fa",lavFMrXsh:"fff0f5",lawngYF:"7cfc00",NmoncEffon:"fffacd",ZXe:"add8e6",ZcSO:"f08080",Zcyan:"e0ffff",ZgTMnPdLw:"fafad2",ZWay:"d3d3d3",ZgYF:"90ee90",ZgYy:"d3d3d3",ZpRk:"ffb6c1",ZsOmon:"ffa07a",ZsHgYF:"20b2aa",ZskyXe:"87cefa",ZUWay:"778899",ZUgYy:"778899",ZstAlXe:"b0c4de",ZLw:"ffffe0",lime:"ff00",limegYF:"32cd32",lRF:"faf0e6",magFta:"ff00ff",maPon:"800000",VaquamarRe:"66cdaa",VXe:"cd",VScEd:"ba55d3",VpurpN:"9370db",VsHgYF:"3cb371",VUXe:"7b68ee",VsprRggYF:"fa9a",VQe:"48d1cc",VviTetYd:"c71585",midnightXe:"191970",mRtcYam:"f5fffa",mistyPse:"ffe4e1",moccasR:"ffe4b5",navajowEte:"ffdead",navy:"80",Tdlace:"fdf5e6",Tive:"808000",TivedBb:"6b8e23",Sange:"ffa500",SangeYd:"ff4500",ScEd:"da70d6",pOegTMnPd:"eee8aa",pOegYF:"98fb98",pOeQe:"afeeee",pOeviTetYd:"db7093",papayawEp:"ffefd5",pHKpuff:"ffdab9",peru:"cd853f",pRk:"ffc0cb",plum:"dda0dd",powMrXe:"b0e0e6",purpN:"800080",YbeccapurpN:"663399",Yd:"ff0000",Psybrown:"bc8f8f",PyOXe:"4169e1",saddNbPwn:"8b4513",sOmon:"fa8072",sandybPwn:"f4a460",sHgYF:"2e8b57",sHshell:"fff5ee",siFna:"a0522d",silver:"c0c0c0",skyXe:"87ceeb",UXe:"6a5acd",UWay:"708090",UgYy:"708090",snow:"fffafa",sprRggYF:"ff7f",stAlXe:"4682b4",tan:"d2b48c",teO:"8080",tEstN:"d8bfd8",tomato:"ff6347",Qe:"40e0d0",viTet:"ee82ee",JHt:"f5deb3",wEte:"ffffff",wEtesmoke:"f5f5f5",Lw:"ffff00",LwgYF:"9acd32"};let Ht;function jt(t){Ht||(Ht=function(){const t={},e=Object.keys(Wt),i=Object.keys(Nt);let s,n,o,a,r;for(s=0;s<e.length;s++){for(a=r=e[s],n=0;n<i.length;n++)o=i[n],r=r.replace(o,Nt[o]);o=parseInt(Wt[a],16),t[r]=[o>>16&255,o>>8&255,255&o]}return t}(),Ht.transparent=[0,0,0,0]);const e=Ht[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}const $t=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const Yt=t=>t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055,Ut=t=>t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4);function Xt(t,e,i){if(t){let s=It(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:Line truncated
|
||||
*/function _t(t){return t+.5|0}const yt=(t,e,i)=>Math.max(Math.min(t,i),e);function vt(t){return yt(_t(2.55*t),0,255)}function Mt(t){return yt(_t(255*t),0,255)}function wt(t){return yt(_t(t/2.55)/100,0,1)}function kt(t){return yt(_t(100*t),0,100)}const St={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},Pt=[..."0123456789ABCDEF"],Dt=t=>Pt[15&t],Ct=t=>Pt[(240&t)>>4]+Pt[15&t],Ot=t=>(240&t)>>4==(15&t);function At(t){var e=(t=>Ot(t.r)&&Ot(t.g)&&Ot(t.b)&&Ot(t.a))(t)?Dt:Ct;return t?"#"+e(t.r)+e(t.g)+e(t.b)+((t,e)=>t<255?e(t):"")(t.a,e):void 0}const Tt=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function Lt(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function Et(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function Rt(t,e,i){const s=Lt(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function It(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=function(t,e,i,s,n){return t===n?(e-i)/s+(e<i?6:0):e===n?(i-t)/s+2:(t-e)/s+4}(e,i,s,h,n),r=60*r+.5),[0|r,l||0,a]}function zt(t,e,i,s){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,s)).map(Mt)}function Ft(t,e,i){return zt(Lt,t,e,i)}function Vt(t){return(t%360+360)%360}function Bt(t){const e=Tt.exec(t);let i,s=255;if(!e)return;e[5]!==i&&(s=e[6]?vt(+e[5]):Mt(+e[5]));const n=Vt(+e[2]),o=+e[3]/100,a=+e[4]/100;return i="hwb"===e[1]?function(t,e,i){return zt(Rt,t,e,i)}(n,o,a):"hsv"===e[1]?function(t,e,i){return zt(Et,t,e,i)}(n,o,a):Ft(n,o,a),{r:i[0],g:i[1],b:i[2],a:s}}const Wt={x:"dark",Z:"light",Y:"re",X:"blu",W:"gr",V:"medium",U:"slate",A:"ee",T:"ol",S:"or",B:"ra",C:"lateg",D:"ights",R:"in",Q:"turquois",E:"hi",P:"ro",O:"al",N:"le",M:"de",L:"yello",F:"en",K:"ch",G:"arks",H:"ea",I:"ightg",J:"wh"},Nt={OiceXe:"f0f8ff",antiquewEte:"faebd7",aqua:"ffff",aquamarRe:"7fffd4",azuY:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"0",blanKedOmond:"ffebcd",Xe:"ff",XeviTet:"8a2be2",bPwn:"a52a2a",burlywood:"deb887",caMtXe:"5f9ea0",KartYuse:"7fff00",KocTate:"d2691e",cSO:"ff7f50",cSnflowerXe:"6495ed",cSnsilk:"fff8dc",crimson:"dc143c",cyan:"ffff",xXe:"8b",xcyan:"8b8b",xgTMnPd:"b8860b",xWay:"a9a9a9",xgYF:"6400",xgYy:"a9a9a9",xkhaki:"bdb76b",xmagFta:"8b008b",xTivegYF:"556b2f",xSange:"ff8c00",xScEd:"9932cc",xYd:"8b0000",xsOmon:"e9967a",xsHgYF:"8fbc8f",xUXe:"483d8b",xUWay:"2f4f4f",xUgYy:"2f4f4f",xQe:"ced1",xviTet:"9400d3",dAppRk:"ff1493",dApskyXe:"bfff",dimWay:"696969",dimgYy:"696969",dodgerXe:"1e90ff",fiYbrick:"b22222",flSOwEte:"fffaf0",foYstWAn:"228b22",fuKsia:"ff00ff",gaRsbSo:"dcdcdc",ghostwEte:"f8f8ff",gTd:"ffd700",gTMnPd:"daa520",Way:"808080",gYF:"8000",gYFLw:"adff2f",gYy:"808080",honeyMw:"f0fff0",hotpRk:"ff69b4",RdianYd:"cd5c5c",Rdigo:"4b0082",ivSy:"fffff0",khaki:"f0e68c",lavFMr:"e6e6fa",lavFMrXsh:"fff0f5",lawngYF:"7cfc00",NmoncEffon:"fffacd",ZXe:"add8e6",ZcSO:"f08080",Zcyan:"e0ffff",ZgTMnPdLw:"fafad2",ZWay:"d3d3d3",ZgYF:"90ee90",ZgYy:"d3d3d3",ZpRk:"ffb6c1",ZsOmon:"ffa07a",ZsHgYF:"20b2aa",ZskyXe:"87cefa",ZUWay:"778899",ZUgYy:"778899",ZstAlXe:"b0c4de",ZLw:"ffffe0",lime:"ff00",limegYF:"32cd32",lRF:"faf0e6",magFta:"ff00ff",maPon:"800000",VaquamarRe:"66cdaa",VXe:"cd",VScEd:"ba55d3",VpurpN:"9370db",VsHgYF:"3cb371",VUXe:"7b68ee",VsprRggYF:"fa9a",VQe:"48d1cc",VviTetYd:"c71585",midnightXe:"191970",mRtcYam:"f5fffa",mistyPse:"ffe4e1",moccasR:"ffe4b5",navajowEte:"ffdead",navy:"80",Tdlace:"fdf5e6",Tive:"808000",TivedBb:"6b8e23",Sange:"ffa500",SangeYd:"ff4500",ScEd:"da70d6",pOegTMnPd:"eee8aa",pOegYF:"98fb98",pOeQe:"afeeee",pOeviTetYd:"db7093",papayawEp:"ffefd5",pHKpuff:"ffdab9",peru:"cd853f",pRk:"ffc0cb",plum:"dda0dd",powMrXe:"b0e0e6",purpN:"800080",YbeccapurpN:"663399",Yd:"ff0000",Psybrown:"bc8f8f",PyOXe:"4169e1",saddNbPwn:"8b4513",sOmon:"fa8072",sandybPwn:"f4a460",sHgYF:"2e8b57",sHshell:"fff5ee",siFna:"a0522d",silver:"c0c0c0",skyXe:"87ceeb",UXe:"6a5acd",UWay:"708090",UgYy:"708090",snow:"fffafa",sprRggYF:"ff7f",stAlXe:"4682b4",tan:"d2b48c",teO:"8080",tEstN:"d8bfd8",tomato:"ff6347",Qe:"40e0d0",viTet:"ee82ee",JHt:"f5deb3",wEte:"ffffff",wEtesmoke:"f5f5f5",Lw:"ffff00",LwgYF:"9acd32"};let Ht;function jt(t){Ht||(Ht=function(){const t={},e=Object.keys(Nt),i=Object.keys(Wt);let s,n,o,a,r;for(s=0;s<e.length;s++){for(a=r=e[s],n=0;n<i.length;n++)o=i[n],r=r.replace(o,Wt[o]);o=parseInt(Nt[a],16),t[r]=[o>>16&255,o>>8&255,255&o]}return t}(),Ht.transparent=[0,0,0,0]);const e=Ht[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}const $t=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const Yt=t=>t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055,Ut=t=>t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4);function Xt(t,e,i){if(t){let s=It(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:Line truncated
|
||||
//# sourceMappingURL=chart.umd.js.map
|
||||
@@ -29,7 +29,7 @@
|
||||
@font-size-ratio__base: 1.4; // Defines ratio of the root font-size to the base font-size
|
||||
|
||||
@font-size-unit: rem; // The unit to which most typography values will be converted by default
|
||||
@font-size-unit-ratio: unit(@root__font-size * 16/100); // Ratio of the root font-size to the font-size unit
|
||||
@font-size-unit-ratio: unit((@root__font-size * 16/100)); // Ratio of the root font-size to the font-size unit
|
||||
@font-size-unit-convert: true; // Controls whether font-size values are converted to the specified font-size unit
|
||||
|
||||
@font-size__base: unit(@font-size-unit-ratio * @font-size-ratio__base, px); // Base font size value in <b>px</b>
|
||||
@@ -73,8 +73,8 @@
|
||||
@indent__xl: @indent__base * 2; // 40px
|
||||
@indent__l: @indent__base * 1.5; // 30px
|
||||
@indent__m: @indent__base * 1.25; // 25px
|
||||
@indent__s: @indent__base / 2; // 10px
|
||||
@indent__xs: @indent__base / 4; // 5px
|
||||
@indent__s: (@indent__base / 2); // 10px
|
||||
@indent__xs: (@indent__base / 4); // 5px
|
||||
|
||||
//
|
||||
// Borders
|
||||
|
||||
Vendored
+30
-18
@@ -1,12 +1,12 @@
|
||||
/*!
|
||||
* jQuery JavaScript Library v3.7.0
|
||||
* jQuery JavaScript Library v3.7.1
|
||||
* https://jquery.com/
|
||||
*
|
||||
* Copyright OpenJS Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* https://jquery.org/license
|
||||
*
|
||||
* Date: 2023-05-11T18:29Z
|
||||
* Date: 2023-08-28T13:37Z
|
||||
*/
|
||||
( function( global, factory ) {
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
|
||||
|
||||
|
||||
var version = "3.7.0",
|
||||
var version = "3.7.1",
|
||||
|
||||
rhtmlSuffix = /HTML$/i,
|
||||
|
||||
@@ -411,9 +411,14 @@
|
||||
// Do not traverse comment nodes
|
||||
ret += jQuery.text( node );
|
||||
}
|
||||
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
|
||||
}
|
||||
if ( nodeType === 1 || nodeType === 11 ) {
|
||||
return elem.textContent;
|
||||
} else if ( nodeType === 3 || nodeType === 4 ) {
|
||||
}
|
||||
if ( nodeType === 9 ) {
|
||||
return elem.documentElement.textContent;
|
||||
}
|
||||
if ( nodeType === 3 || nodeType === 4 ) {
|
||||
return elem.nodeValue;
|
||||
}
|
||||
|
||||
@@ -1126,12 +1131,17 @@
|
||||
documentElement.msMatchesSelector;
|
||||
|
||||
// Support: IE 9 - 11+, Edge 12 - 18+
|
||||
// Accessing iframe documents after unload throws "permission denied" errors (see trac-13936)
|
||||
// Support: IE 11+, Edge 17 - 18+
|
||||
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
||||
// two documents; shallow comparisons work.
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if ( preferredDoc != document &&
|
||||
// Accessing iframe documents after unload throws "permission denied" errors
|
||||
// (see trac-13936).
|
||||
// Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`,
|
||||
// all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well.
|
||||
if ( documentElement.msMatchesSelector &&
|
||||
|
||||
// Support: IE 11+, Edge 17 - 18+
|
||||
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
||||
// two documents; shallow comparisons work.
|
||||
// eslint-disable-next-line eqeqeq
|
||||
preferredDoc != document &&
|
||||
( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
|
||||
|
||||
// Support: IE 9 - 11+, Edge 12 - 18+
|
||||
@@ -2694,12 +2704,12 @@
|
||||
jQuery.expr[ ":" ] = jQuery.expr.pseudos;
|
||||
jQuery.unique = jQuery.uniqueSort;
|
||||
|
||||
// These have always been private, but they used to be documented
|
||||
// as part of Sizzle so let's maintain them in the 3.x line
|
||||
// for backwards compatibility purposes.
|
||||
// These have always been private, but they used to be documented as part of
|
||||
// Sizzle so let's maintain them for now for backwards compatibility purposes.
|
||||
find.compile = compile;
|
||||
find.select = select;
|
||||
find.setDocument = setDocument;
|
||||
find.tokenize = tokenize;
|
||||
|
||||
find.escape = jQuery.escapeSelector;
|
||||
find.getText = jQuery.text;
|
||||
@@ -5913,7 +5923,7 @@
|
||||
if ( hasScripts ) {
|
||||
doc = scripts[ scripts.length - 1 ].ownerDocument;
|
||||
|
||||
// Reenable scripts
|
||||
// Re-enable scripts
|
||||
jQuery.map( scripts, restoreScript );
|
||||
|
||||
// Evaluate executable scripts on first document insertion
|
||||
@@ -6370,7 +6380,7 @@
|
||||
trChild = document.createElement( "div" );
|
||||
|
||||
table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
|
||||
tr.style.cssText = "border:1px solid";
|
||||
tr.style.cssText = "box-sizing:content-box;border:1px solid";
|
||||
|
||||
// Support: Chrome 86+
|
||||
// Height set through cssText does not get applied.
|
||||
@@ -6382,7 +6392,7 @@
|
||||
// In our bodyBackground.html iframe,
|
||||
// display for all div elements is set to "inline",
|
||||
// which causes a problem only in Android 8 Chrome 86.
|
||||
// Ensuring the div is display: block
|
||||
// Ensuring the div is `display: block`
|
||||
// gets around this issue.
|
||||
trChild.style.display = "block";
|
||||
|
||||
@@ -10550,7 +10560,9 @@
|
||||
},
|
||||
|
||||
hover: function( fnOver, fnOut ) {
|
||||
return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
|
||||
return this
|
||||
.on( "mouseenter", fnOver )
|
||||
.on( "mouseleave", fnOut || fnOver );
|
||||
}
|
||||
} );
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -1,2 +1,2 @@
|
||||
/*! jQuery v3.7.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */
|
||||
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.0",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}function fe(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}ce.fn=ce.prototype={jquery:t,constructor:ce,length:0,toArray:function(){return ae.call(this)},get:function(e){return null==e?ae.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=ce.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return ce.each(this,e)},map:function(n){return this.pushStack(ce.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(ae.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(ce.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(ce.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:oe.sort,splice:oe.splice},ce.extend=ce.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||v(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(ce.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||ce.isPlainObject(n)?n:{},i=!1,a[t]=ce.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},ce.extend({expando:"jQuery"+(t+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==i.call(e))&&(!(t=r(e))||"function"==typeof(n=ue.call(t,"constructor")&&t.constructor)&&o.call(n)===a)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){m(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(c(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},text:function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i)return e.textContent;if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=ce.text(t);return n},makeArray:function(e,t){var n=t||[];return null!=e&&(c(Object(e))?ce.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:se.call(t,e,n)},isXMLDoc:function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!l.test(t||n&&n.nodeName||"HTML")},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(c(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:le}),"function"==typeof Symbol&&(ce.fn[Symbol.iterator]=oe[Symbol.iterator]),ce.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var pe=oe.pop,de=oe.sort,he=oe.splice,ge="[\\x20\\t\\r\\n\\f]",ve=new RegExp("^"+ge+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ge+"+$","g");ce.contains=function(e,t){var n=t&&t.parentNode;return e===n||!(!n||1!==n.nodeType||!(e.contains?e.contains(n):e.compareDocumentPosition&&16&e.compareDocumentPosition(n)))};var f=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;function p(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e}ce.escapeSelector=function(e){return(e+"").replace(f,p)};var ye=C,me=s;!function(){var e,b,w,o,a,T,r,C,d,i,k=me,S=ce.expando,E=0,n=0,s=W(),c=W(),u=W(),h=W(),l=function(e,t){return e===t&&(a=!0),0},f="checked|selected|async|autofocus|autoplay|controlLine truncated
|
||||
/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */
|
||||
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}function fe(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}ce.fn=ce.prototype={jquery:t,constructor:ce,length:0,toArray:function(){return ae.call(this)},get:function(e){return null==e?ae.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=ce.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return ce.each(this,e)},map:function(n){return this.pushStack(ce.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(ae.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(ce.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(ce.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:oe.sort,splice:oe.splice},ce.extend=ce.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||v(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(ce.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||ce.isPlainObject(n)?n:{},i=!1,a[t]=ce.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},ce.extend({expando:"jQuery"+(t+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==i.call(e))&&(!(t=r(e))||"function"==typeof(n=ue.call(t,"constructor")&&t.constructor)&&o.call(n)===a)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){m(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(c(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},text:function(e){var t,n="",r=0,i=e.nodeType;if(!i)while(t=e[r++])n+=ce.text(t);return 1===i||11===i?e.textContent:9===i?e.documentElement.textContent:3===i||4===i?e.nodeValue:n},makeArray:function(e,t){var n=t||[];return null!=e&&(c(Object(e))?ce.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:se.call(t,e,n)},isXMLDoc:function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!l.test(t||n&&n.nodeName||"HTML")},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(c(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:le}),"function"==typeof Symbol&&(ce.fn[Symbol.iterator]=oe[Symbol.iterator]),ce.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var pe=oe.pop,de=oe.sort,he=oe.splice,ge="[\\x20\\t\\r\\n\\f]",ve=new RegExp("^"+ge+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ge+"+$","g");ce.contains=function(e,t){var n=t&&t.parentNode;return e===n||!(!n||1!==n.nodeType||!(e.contains?e.contains(n):e.compareDocumentPosition&&16&e.compareDocumentPosition(n)))};var f=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;function p(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e}ce.escapeSelector=function(e){return(e+"").replace(f,p)};var ye=C,me=s;!function(){var e,b,w,o,a,T,r,C,d,i,k=me,S=ce.expando,E=0,n=0,s=W(),c=W(),u=W(),h=W(),l=function(e,t){return e===t&&(a=!0),0},f="checked|selected|async|autofocus|autoplay|conLine truncated
|
||||
@@ -13,7 +13,7 @@
|
||||
}(function ($, undefined) {
|
||||
"use strict";
|
||||
/*!
|
||||
* jsTree 3.3.15
|
||||
* jsTree 3.3.16
|
||||
* http://jstree.com/
|
||||
*
|
||||
* Copyright (c) 2014 Ivan Bozhanov (http://vakata.com)
|
||||
@@ -63,7 +63,7 @@
|
||||
* specifies the jstree version in use
|
||||
* @name $.jstree.version
|
||||
*/
|
||||
version : '3.3.15',
|
||||
version : '3.3.16',
|
||||
/**
|
||||
* holds all the default options used when creating new instances
|
||||
* @name $.jstree.defaults
|
||||
@@ -528,7 +528,12 @@
|
||||
e.preventDefault();
|
||||
this.edit(e.currentTarget);
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Should reselecting an already selected node trigger the select and changed callbacks
|
||||
* @name $.jstree.defaults.core.allow_reselect
|
||||
*/
|
||||
allow_reselect : false
|
||||
};
|
||||
$.jstree.core.prototype = {
|
||||
/**
|
||||
@@ -3172,7 +3177,7 @@
|
||||
this.deselect_node(obj, false, e);
|
||||
}
|
||||
else {
|
||||
if (!this.is_selected(obj) || this._data.core.selected.length !== 1) {
|
||||
if (this.settings.core.allow_reselect || !this.is_selected(obj) || this._data.core.selected.length !== 1) {
|
||||
this.deselect_all(true);
|
||||
this.select_node(obj, false, false, e);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/*! js-cookie v3.0.1 | MIT */
|
||||
/*! js-cookie v3.0.5 | MIT */
|
||||
;
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = global || self, (function () {
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, (function () {
|
||||
var current = global.Cookies;
|
||||
var exports = global.Cookies = factory();
|
||||
exports.noConflict = function () { global.Cookies = current; return exports; };
|
||||
}()));
|
||||
}(this, (function () { 'use strict';
|
||||
})());
|
||||
})(this, (function () { 'use strict';
|
||||
|
||||
/* eslint-disable no-var */
|
||||
function assign (target) {
|
||||
@@ -42,7 +42,7 @@
|
||||
/* eslint-disable no-var */
|
||||
|
||||
function init (converter, defaultAttributes) {
|
||||
function set (key, value, attributes) {
|
||||
function set (name, value, attributes) {
|
||||
if (typeof document === 'undefined') {
|
||||
return
|
||||
}
|
||||
@@ -56,7 +56,7 @@
|
||||
attributes.expires = attributes.expires.toUTCString();
|
||||
}
|
||||
|
||||
key = encodeURIComponent(key)
|
||||
name = encodeURIComponent(name)
|
||||
.replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)
|
||||
.replace(/[()]/g, escape);
|
||||
|
||||
@@ -83,11 +83,11 @@
|
||||
}
|
||||
|
||||
return (document.cookie =
|
||||
key + '=' + converter.write(value, key) + stringifiedAttributes)
|
||||
name + '=' + converter.write(value, name) + stringifiedAttributes)
|
||||
}
|
||||
|
||||
function get (key) {
|
||||
if (typeof document === 'undefined' || (arguments.length && !key)) {
|
||||
function get (name) {
|
||||
if (typeof document === 'undefined' || (arguments.length && !name)) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -100,25 +100,25 @@
|
||||
var value = parts.slice(1).join('=');
|
||||
|
||||
try {
|
||||
var foundKey = decodeURIComponent(parts[0]);
|
||||
jar[foundKey] = converter.read(value, foundKey);
|
||||
var found = decodeURIComponent(parts[0]);
|
||||
jar[found] = converter.read(value, found);
|
||||
|
||||
if (key === foundKey) {
|
||||
if (name === found) {
|
||||
break
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
return key ? jar[key] : jar
|
||||
return name ? jar[name] : jar
|
||||
}
|
||||
|
||||
return Object.create(
|
||||
{
|
||||
set: set,
|
||||
get: get,
|
||||
remove: function (key, attributes) {
|
||||
set,
|
||||
get,
|
||||
remove: function (name, attributes) {
|
||||
set(
|
||||
key,
|
||||
name,
|
||||
'',
|
||||
assign({}, attributes, {
|
||||
expires: -1
|
||||
@@ -144,4 +144,4 @@
|
||||
|
||||
return api;
|
||||
|
||||
})));
|
||||
}));
|
||||
Vendored
+4
-3
@@ -1,10 +1,11 @@
|
||||
/**
|
||||
* Less - Leaner CSS v3.13.1
|
||||
* Less - Leaner CSS v4.2.0
|
||||
* http://lesscss.org
|
||||
*
|
||||
* Copyright (c) 2009-2020, Alexis Sellier <self@cloudhead.net>
|
||||
* Copyright (c) 2009-2023, Alexis Sellier <self@cloudhead.net>
|
||||
* Licensed under the Apache-2.0 License.
|
||||
*
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).less=t()}(this,(function(){"use strict";function e(e){return e.replace(/^[a-z-]+:\/+?[^\/]+/,"").replace(/[\?\&]livereload=\w+/,"").replace(/^\//,"").replace(/\.[a-zA-Z]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function t(e,t){for(var i in t.dataset)if(t.dataset.hasOwnProperty(i))if("env"===i||"dumpLineNumbers"===i||"rootpath"===i||"errorReporting"===i)e[i]=t.dataset[i];else try{e[i]=JSON.parse(t.dataset[i])}catch(e){}}var i=function(t,i,n){var r=n.href||"",s="less:"+(n.title||e(r)),o=t.getElementById(s),a=!1,l=t.createElement("style");l.setAttribute("type","text/css"),n.media&&l.setAttribute("media",n.media),l.id=s,l.styleSheet||(l.appendChild(t.createTextNode(i)),a=null!==o&&o.childNodes.length>0&&l.childNodes.length>0&&o.firstChild.nodeValue===l.firstChild.nodeValue);var u=t.getElementsByTagName("head")[0];if(null===o||!1===a){var h=n&&n.nextSibling||null;h?h.parentNode.insertBefore(l,h):u.appendChild(l)}if(o&&!1===a&&o.parentNode.removeChild(o),l.styleSheet)try{l.styleSheet.cssText=i}catch(e){throw new Error("Couldn't reassign styleSheet.cssText.")}},n=function(e){var t,i=e.document;return i.currentScript||(t=i.getElementsByTagName("script"))[t.length-1]},r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var i in t)t.hasOwnProperty(i)&&(e[i]=t[i])})(e,t)};function s(e,t){function i(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(i.prototype=t.prototype,new i)}function o(){for(var e=0,t=0,i=arguments.length;t<i;t++)e+=arguments[t].length;var n=Array(e),r=0;for(t=0;t<i;t++)for(var s=arguments[t],o=0,a=s.length;o<a;o++,r++)n[r]=s[o];return n}var a={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},l={length:{m:1,cm:.01,mm:.001,in:.0254,px:.0254/96,pt:.0254/72,pc:.0254/72*12},duration:{s:1,ms:.001},angle:{rad:1/(2*Math.PI),deg:1/360,grad:1/400,turn:1}},u={colors:a,unitConversions:l},h=function(){function e(){thiLine truncated
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).less=t()}(this,(function(){"use strict";function e(e){return e.replace(/^[a-z-]+:\/+?[^/]+/,"").replace(/[?&]livereload=\w+/,"").replace(/^\//,"").replace(/\.[a-zA-Z]+$/,"").replace(/[^.\w-]+/g,"-").replace(/\./g,":")}function t(e,t){if(t)for(var i in t.dataset)if(Object.prototype.hasOwnProperty.call(t.dataset,i))if("env"===i||"dumpLineNumbers"===i||"rootpath"===i||"errorReporting"===i)e[i]=t.dataset[i];else try{e[i]=JSON.parse(t.dataset[i])}catch(e){}}var i=function(t,i,n){var r=n.href||"",s="less:"+(n.title||e(r)),o=t.getElementById(s),a=!1,l=t.createElement("style");l.setAttribute("type","text/css"),n.media&&l.setAttribute("media",n.media),l.id=s,l.styleSheet||(l.appendChild(t.createTextNode(i)),a=null!==o&&o.childNodes.length>0&&l.childNodes.length>0&&o.firstChild.nodeValue===l.firstChild.nodeValue);var u=t.getElementsByTagName("head")[0];if(null===o||!1===a){var c=n&&n.nextSibling||null;c?c.parentNode.insertBefore(l,c):u.appendChild(l)}if(o&&!1===a&&o.parentNode.removeChild(o),l.styleSheet)try{l.styleSheet.cssText=i}catch(e){throw new Error("Couldn't reassign styleSheet.cssText.")}},n=function(e){var t,i=e.document;return i.currentScript||(t=i.getElementsByTagName("script"))[t.length-1]},r={error:function(e){this._fireEvent("error",e)},warn:function(e){this._fireEvent("warn",e)},info:function(e){this._fireEvent("info",e)},debug:function(e){this._fireEvent("debug",e)},addListener:function(e){this._listeners.push(e)},removeListener:function(e){for(var t=0;t<this._listeners.length;t++)if(this._listeners[t]===e)return void this._listeners.splice(t,1)},_fireEvent:function(e,t){for(var i=0;i<this._listeners.length;i++){var n=this._listeners[i][e];n&&n(t)}},_listeners:[]},s=function(){function e(e,t){this.fileManagers=t||[],e=e||{};for(var i=[],n=i.concat(["encodeBase64","mimeLookup","charsetLookup","getSourceMapGenerator"]),r=0;r<n.length;r++){var s=n[r],o=e[s];o?this[s]=o.bind(e):r<i.length&&this.warn("missing required function in environment - "+s)}}return e.prototype.getFileManager=function(e,t,i,n,s){e||r.warn("getFileManager called with no filename.. Please report this issue. continuing."),void 0===t&&r.warn("getFileManager called with null directory.. Please report this issue. continuing.");var o=this.fileManagers;i.pluginManager&&(o=[].concat(o).concat(i.pluginManager.getFileManagers()));for(var a=o.length-1;a>=0;a--){var l=o[a];if(l[s?"supportsSync":"supports"](e,t,i,n))return l}return null},e.prototype.addFileManager=function(e){this.fileManagers.push(e)},e.prototype.clearFileManagers=function(){this.fileManagers=[]},e}(),o={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"Line truncated
|
||||
//# sourceMappingURL=less.min.js.map
|
||||
+4
-4
@@ -14,20 +14,20 @@
|
||||
"grunt-banner": "~0.6.0",
|
||||
"grunt-continue": "~0.1.0",
|
||||
"grunt-contrib-clean": "~2.0.1",
|
||||
"grunt-contrib-connect": "~3.0.0",
|
||||
"grunt-contrib-cssmin": "~4.0.0",
|
||||
"grunt-contrib-connect": "~4.0.0",
|
||||
"grunt-contrib-cssmin": "~5.0.0",
|
||||
"grunt-contrib-imagemin": "~4.0.0",
|
||||
"grunt-contrib-jasmine": "~4.0.0",
|
||||
"grunt-contrib-less": "~3.0.0",
|
||||
"grunt-contrib-watch": "~1.1.0",
|
||||
"grunt-eslint": "~24.2.0",
|
||||
"grunt-eslint": "~24.3.0",
|
||||
"grunt-exec": "~3.0.0",
|
||||
"grunt-replace": "~2.0.2",
|
||||
"grunt-styledocco": "~0.3.0",
|
||||
"grunt-template-jasmine-requirejs": "~0.2.3",
|
||||
"grunt-text-replace": "~0.4.0",
|
||||
"imagemin-svgo": "~9.0.0",
|
||||
"less": "4.1.3",
|
||||
"less": "4.2.0",
|
||||
"load-grunt-config": "~4.0.1",
|
||||
"morgan": "~1.10.0",
|
||||
"node-minify": "~3.6.0",
|
||||
|
||||
@@ -39,7 +39,7 @@ class SimpleProductsFixture extends Fixture
|
||||
/**
|
||||
* Simple product sku pattern
|
||||
*/
|
||||
const SKU_PATTERN = 'product_dynamic_%s';
|
||||
public const SKU_PATTERN = 'product_dynamic_%s';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
@@ -257,6 +257,12 @@ class SimpleProductsFixture extends Fixture
|
||||
'category_ids' => function ($index, $entityNumber) {
|
||||
return $this->websiteCategoryProvider->getCategoryId($index);
|
||||
},
|
||||
'meta_keyword' => function ($productId) {
|
||||
return sprintf($this->getSkuPattern(), $productId);
|
||||
},
|
||||
'meta_title' => function ($productId) {
|
||||
return sprintf($this->getSkuPattern(), $productId);
|
||||
},
|
||||
'attribute_set_id' => $attributeSet,
|
||||
'additional_attributes' => $additionalAttributes,
|
||||
'status' => function () {
|
||||
|
||||
@@ -39,7 +39,7 @@ class SimpleProductTemplateGenerator implements TemplateEntityGeneratorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function generateEntity()
|
||||
{
|
||||
@@ -70,6 +70,9 @@ class SimpleProductTemplateGenerator implements TemplateEntityGeneratorInterface
|
||||
'name' => 'template name' . $productRandomizerNumber,
|
||||
'url_key' => 'template-url' . $productRandomizerNumber,
|
||||
'sku' => 'template_sku_simple' . $productRandomizerNumber,
|
||||
'meta_description' => 'Simple Product',
|
||||
'meta_keyword' => $productRandomizerNumber,
|
||||
'meta_title' => $productRandomizerNumber,
|
||||
'price' => 10,
|
||||
'visibility' => Visibility::VISIBILITY_BOTH,
|
||||
'status' => Status::STATUS_ENABLED,
|
||||
|
||||
@@ -137,6 +137,11 @@ class FileClassScanner
|
||||
// `class` token is not used with a valid class name
|
||||
} elseif ($triggerClass && !$tokenIsArray) {
|
||||
$triggerClass = false;
|
||||
// `class` token was used as a string; not to define class
|
||||
// phpstan:ignore
|
||||
} elseif ($triggerClass && empty($class) && $token[0] === T_DOUBLE_ARROW) {
|
||||
$triggerClass = false;
|
||||
continue;
|
||||
// The class keyword was found in the last loop
|
||||
} elseif ($triggerClass && $token[0] === T_STRING) {
|
||||
$triggerClass = false;
|
||||
|
||||
Reference in new issue
Block a user