Skip to content

Commit 06e994b

Browse files
ACPT-1186
Resolving failures in GraphQlStateTest after merge
1 parent 3373022 commit 06e994b

File tree

8 files changed

+129
-71
lines changed

8 files changed

+129
-71
lines changed

dev/tests/integration/testsuite/Magento/GraphQl/App/GraphQlStateTest.php

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,14 @@ protected function tearDown(): void
8989
* @return void
9090
* @throws \Exception
9191
*/
92-
public function testCustomerState(string $query, array $variables, array $variables2, array $authInfo, string $operationName, string $expected)
93-
{
92+
public function testCustomerState(
93+
string $query,
94+
array $variables,
95+
array $variables2,
96+
array $authInfo,
97+
string $operationName,
98+
string $expected,
99+
) : void {
94100
if ($operationName === 'createCustomer') {
95101
$this->customerRepository = $this->objectManagerForTest->get(CustomerRepositoryInterface::class);
96102
$this->registry = $this->objectManagerForTest->get(Registry::class);
@@ -132,12 +138,19 @@ public function testState(
132138
string $operationName,
133139
string $expected,
134140
): void {
141+
if (array_key_exists(1, $authInfo)) {
142+
$authInfo1 = $authInfo[0];
143+
$authInfo2 = $authInfo[1];
144+
} else {
145+
$authInfo1 = $authInfo;
146+
$authInfo2 = $authInfo;
147+
}
135148
$jsonEncodedRequest = json_encode([
136149
'query' => $query,
137150
'variables' => $variables,
138151
'operationName' => $operationName
139152
]);
140-
$output1 = $this->request($jsonEncodedRequest, $operationName, $authInfo, true);
153+
$output1 = $this->request($jsonEncodedRequest, $operationName, $authInfo1, true);
141154
$this->assertStringContainsString($expected, $output1);
142155
if ($variables2) {
143156
$jsonEncodedRequest = json_encode([
@@ -146,7 +159,7 @@ public function testState(
146159
'operationName' => $operationName
147160
]);
148161
}
149-
$output2 = $this->request($jsonEncodedRequest, $operationName, $authInfo);
162+
$output2 = $this->request($jsonEncodedRequest, $operationName, $authInfo2);
150163
$this->assertStringContainsString($expected, $output2);
151164
}
152165

@@ -589,9 +602,12 @@ public function customerDataProvider(): array
589602
QUERY,
590603
['email' => 'customer2@example.com', 'password' => 'password'],
591604
['email' => 'customer@example.com', 'password' => 'password'],
592-
['email' => 'customer@example.com', 'password' => 'password'],
605+
[
606+
['email' => 'customer@example.com', 'password' => 'password'],
607+
['email' => 'customer2@example.com', 'password' => 'password'],
608+
],
593609
'updateCustomerEmail',
594-
'email'
610+
'email',
595611
],
596612
'Generate Customer Token' => [
597613
<<<'QUERY'

dev/tests/integration/testsuite/Magento/GraphQl/App/State/Collector.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,6 @@ public function getPropertiesConstructedAndCurrent(): array
126126
}
127127
// Calling _resetState helps us avoid adding skip/filter for these classes.
128128
$objectManager->resetStateWeakMapObjects();
129-
/* Note: We must force garbage collection to clean up cyclic referenced objects after _resetState()
130-
Otherwise, they may still show up in the WeakMap. */
131-
gc_collect_cycles();
132129
$objects = [];
133130
foreach ($objectManager->getWeakMap() as $object => $propertiesBefore) {
134131
$objects[] = new CollectedObjectConstructedAndCurrent(
@@ -154,21 +151,21 @@ public function getPropertiesFromObject(
154151
CompareType $compareType,
155152
int $recursionLevel = 1,
156153
): CollectedObject {
157-
if ($recursionLevel < 0) {
158-
return CollectedObject::getRecursionEndObject();
159-
}
160154
$className = get_class($object);
161155
$skipList = $compareType == CompareType::CompareBetweenRequests ?
162156
$this->skipListBetweenRequests : $this->skipListFromConstructed ;
163157
if (array_key_exists($className, $skipList)) {
164158
return CollectedObject::getSkippedObject();
165159
}
166160
if ($this->objectManager instanceof ObjectManager) {
167-
$serviceName = array_search($object, $this->objectManager->getSharedInstances());
161+
$serviceName = array_search($object, $this->objectManager->getSharedInstances(), true);
168162
if ($serviceName && array_key_exists($serviceName, $skipList)) {
169163
return CollectedObject::getSkippedObject();
170164
}
171165
}
166+
if ($recursionLevel < 0) {
167+
return CollectedObject::getRecursionEndObject();
168+
}
172169
$objReflection = new \ReflectionObject($object);
173170
$properties = [];
174171
foreach ($objReflection->getProperties() as $property) {

dev/tests/integration/testsuite/Magento/GraphQl/App/State/Comparator.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace Magento\GraphQl\App\State;
99

10+
use Magento\Framework\ObjectManager\NoninterceptableInterface;
11+
1012
/**
1113
* Compare object state between requests and between first instantiation by ObjectManager
1214
*/
@@ -100,7 +102,7 @@ public function compareConstructedAgainstCurrent(string $operationName): array
100102
$object = $objectAndProperties->getObject();
101103
$constructedObject = $objectAndProperties->getConstructedCollected();
102104
$currentObject = $objectAndProperties->getCurrentCollected();
103-
if ($object instanceof \Magento\Framework\ObjectManager\NoninterceptableInterface) {
105+
if ($object instanceof NoninterceptableInterface) {
104106
/* All Proxy classes use NoninterceptableInterface. We skip them because for the Proxies that are
105107
loaded, we compare the actual loaded objects. */
106108
continue;
@@ -142,6 +144,10 @@ private function compare(
142144
&& array_key_exists($after->getClassName(), $skipList)) {
143145
return []; // This object should be skipped
144146
}
147+
if (is_a($before->getClassName(), NoninterceptableInterface::class, true)
148+
&& $after->getClassName() == $before->getClassName()) {
149+
return []; // Skip Proxy classes. Their subjects are already compared themselves.
150+
}
145151
if (!$serviceName) {
146152
$serviceName = $before->getClassName();
147153
}
@@ -200,6 +206,10 @@ private function formatValue($value): mixed
200206
$data[$key] = $this->formatValue($value2);
201207
}
202208
return $data;
209+
} elseif (is_resource($value)) {
210+
return ['resource' =>
211+
['resourceId' => get_resource_id($value), 'resourceType' => get_resource_type($value)]
212+
];
203213
}
204214
return $value;
205215
}

dev/tests/integration/testsuite/Magento/GraphQl/App/State/DynamicFactoryDecorator.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ public function create($type, array $arguments = [])
6666
*/
6767
public function _resetState(): void
6868
{
69+
/* Note: We force garbage collection to clean up cyclic referenced objects before _resetState()
70+
This is to prevent calling _resetState() on objects that will be destroyed by garbage collector. */
71+
gc_collect_cycles();
6972
/* Note: we can't iterate weakMap itself because it gets indirectly modified (shrinks) as some of the
7073
* service classes that get reset will destruct some of the other service objects. The iterator to WeakMap
7174
* returns actual objects, not WeakReferences. Therefore, we create a temporary list of weak references which
@@ -84,7 +87,12 @@ public function _resetState(): void
8487
continue;
8588
}
8689
$object->_resetState();
90+
unset($object);
91+
unset($weakReference);
8792
}
93+
/* Note: We must force garbage collection to clean up cyclic referenced objects after _resetState()
94+
Otherwise, they may still show up in the WeakMap. */
95+
gc_collect_cycles();
8896
}
8997

9098
public function getWeakMap() : WeakMap

dev/tests/integration/testsuite/Magento/GraphQl/App/State/SkipListAndFilterList.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class SkipListAndFilterList
1717
*/
1818
private ?array $skipList = null;
1919

20-
private array $filterListByClassNameAndServiceNameCache = [];
20+
private array $filtersByClassNameAndServiceNameCache = [];
2121

2222
/**
2323
* @var array|null
@@ -33,7 +33,7 @@ class SkipListAndFilterList
3333
*/
3434
public function filterProperties(array $properties, array $propertiesToFilterList): array
3535
{
36-
return array_diff_key($properties, ...$propertiesToFilterList);
36+
return array_diff_key($properties, $propertiesToFilterList);
3737
}
3838

3939
/**
@@ -86,8 +86,8 @@ public function getFilterList(): array
8686

8787
public function getFilterListByClassNameAndServiceName(string $className, string $serviceName) : array
8888
{
89-
if ($this->filterListByClassNameAndServiceNameCache[$className][$serviceName] ?? false) {
90-
return $this->filterListByClassNameAndServiceNameCache[$className][$serviceName];
89+
if ($this->filtersByClassNameAndServiceNameCache[$className][$serviceName] ?? false) {
90+
return $this->filtersByClassNameAndServiceNameCache[$className][$serviceName];
9191
}
9292
$filterList = $this->getFilterList();
9393
$filterListParentClasses = $filterList['parents'] ?? [];
@@ -105,7 +105,8 @@ public function getFilterListByClassNameAndServiceName(string $className, string
105105
if ($filterListAll) {
106106
$propertiesToFilterList[] = $filterListAll;
107107
}
108-
$this->filterListByClassNameAndServiceNameCache[$className][$serviceName] = $propertiesToFilterList;
109-
return $propertiesToFilterList;
108+
$propertiesToFilter = array_merge(...$propertiesToFilterList);
109+
$this->filtersByClassNameAndServiceNameCache[$className][$serviceName] = $propertiesToFilter;
110+
return $propertiesToFilter;
110111
}
111112
}

dev/tests/integration/testsuite/Magento/GraphQl/_files/state-filter-list.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
Magento\Framework\ObjectManager\NoninterceptableInterface::class => [
3939
'_subject' => null,
4040
],
41+
Magento\Framework\Logger\Handler\Base::class => [ // TODO: remove this after ACPT-1034 is fixed
42+
'stream' => null,
43+
],
4144
],
4245
'services' => [ // Note: These apply only to the service names that match.
4346
Magento\Framework\ObjectManager\ConfigInterface::class => ['_mergedArguments' => null],
@@ -133,5 +136,54 @@
133136
Magento\Catalog\Model\ResourceModel\Product\Collection::class => ['_conn' => null],
134137
Magento\Catalog\Model\ResourceModel\Category\Collection::class => ['_conn' => null],
135138
Magento\Catalog\Model\Product\Attribute\Backend\Tierprice\Interceptor::class => ['metadataPool' => null, '_attribute' => null],
139+
Magento\Framework\View\Design\Fallback\Rule\Theme::class => [
140+
'directoryList' => null, // FIXME: This should be using a Dependency Injected Proxy instead
141+
],
142+
Magento\Framework\View\Asset\PreProcessor\AlternativeSource::class => [
143+
'alternativesSorted' => null, // Note: just lazy loaded the sorting of alternatives
144+
],
145+
Magento\Directory\Model\Country::class => [
146+
'_origData' => null, // TODO: Do these need to be added to resetState?
147+
'storedData' => null, // Should this class even be reused at all?
148+
'_data' => null,
149+
],
150+
Magento\Directory\Model\Region::class => [
151+
'_origData' => null, // TODO: Do these need to be added to resetState?
152+
'storedData' => null, // Should this class even be reused at all?
153+
'_data' => null,
154+
],
155+
Magento\Framework\View\Layout\Argument\Parser::class => [ // FIXME: Needs to convert to proper dependency...
156+
'converter' => null, // ...injection using constructor and factory
157+
],
158+
Magento\Framework\Communication\Config\Reader\XmlReader\Converter::class => [ // FIXME: Needs to convert to proper dependency...
159+
'configParser' => null, // ...injection using constructor and factory
160+
],
161+
Magento\Webapi\Model\Config::class => [
162+
'services' => null, // 'services' is lazy-loaded which is okay, but we need to verify that it is properly reset after poison pill
163+
],
164+
Magento\WebapiAsync\Model\Config::class => [
165+
'asyncServices' => null, // 'asyncServices' is lazy-loaded which is okay, but we need to verify that it is properly reset after poison pill
166+
],
167+
Magento\Framework\MessageQueue\Publisher\Config\PublisherConnection::class => [
168+
'name' => null, // TODO: Confirm this doesn't change outside of deployment, or if it does, that it resets properly from poison pill
169+
'exchange' => null,
170+
'isDisabled' => null,
171+
],
172+
Magento\Framework\MessageQueue\Publisher\Config\PublisherConfigItem::class => [
173+
'topic' => null, // TODO: Confirm this doesn't change outside of deployment, or if it does, that it resets properly from poison pill
174+
'isDisabled' => null,
175+
],
176+
Magento\Framework\View\File\Collector\Decorator\ModuleDependency::class => [
177+
'orderedModules' => null, // TODO: Confirm this doesn't change outside of deployment
178+
],
179+
Magento\Framework\View\Page\Config::class => [
180+
'builder' => null, // I think this is okay
181+
],
182+
Magento\TestFramework\View\Layout\Interceptor::class => [
183+
'builder' => null,
184+
],
185+
Magento\Theme\Model\ResourceModel\Theme\Collection\Interceptor::class => [
186+
'_itemObjectClass' => null, // FIXME: this looks like it needs to be fixed
187+
],
136188
],
137189
];

0 commit comments

Comments
 (0)