Skip to content

Commit 35abf0b

Browse files
committed
B2B-2259: customAttributeMetadata GraphQl query has no cache identity
- WebAPI tests update keeping query logic that throws an exception
1 parent c7c5c87 commit 35abf0b

File tree

3 files changed

+162
-12
lines changed

3 files changed

+162
-12
lines changed

dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public function get(string $query, array $variables = [], string $operationName
107107
* @return mixed
108108
* @throws \Exception
109109
*/
110-
private function processResponse(string $response)
110+
private function processResponse(string $response, array $responseHeaders = [], array $responseCookies = [])
111111
{
112112
$responseArray = $this->json->jsonDecode($response);
113113

@@ -116,7 +116,7 @@ private function processResponse(string $response)
116116
throw new \Exception('Unknown GraphQL response body: ' . $response);
117117
}
118118

119-
$this->processErrors($responseArray);
119+
$this->processErrors($responseArray, $responseHeaders, $responseCookies);
120120

121121
if (!isset($responseArray['data'])) {
122122
//phpcs:ignore Magento2.Exceptions.DirectThrow
@@ -153,9 +153,9 @@ public function getWithResponseHeaders(
153153
array_filter($requestArray);
154154

155155
$response = $this->curlClient->getWithFullResponse($url, $requestArray, $headers, $flushCookies);
156-
$responseBody = $this->processResponse($response['body']);
157156
$responseHeaders = !empty($response['header']) ? $this->processResponseHeaders($response['header']) : [];
158157
$responseCookies = !empty($response['header']) ? $this->processResponseCookies($response['header']) : [];
158+
$responseBody = $this->processResponse($response['body'], $responseHeaders, $responseCookies);
159159

160160
return ['headers' => $responseHeaders, 'body' => $responseBody, 'cookies' => $responseCookies];
161161
}
@@ -188,9 +188,9 @@ public function postWithResponseHeaders(
188188
$postData = $this->json->jsonEncode($requestArray);
189189

190190
$response = $this->curlClient->postWithFullResponse($url, $postData, $headers, $flushCookies);
191-
$responseBody = $this->processResponse($response['body']);
192191
$responseHeaders = !empty($response['header']) ? $this->processResponseHeaders($response['header']) : [];
193192
$responseCookies = !empty($response['header']) ? $this->processResponseCookies($response['header']) : [];
193+
$responseBody = $this->processResponse($response['body'], $responseHeaders, $responseCookies);
194194

195195
return ['headers' => $responseHeaders, 'body' => $responseBody, 'cookies' => $responseCookies];
196196
}
@@ -201,7 +201,7 @@ public function postWithResponseHeaders(
201201
* @param array $responseBodyArray
202202
* @throws \Exception
203203
*/
204-
private function processErrors($responseBodyArray)
204+
private function processErrors($responseBodyArray, array $responseHeaders = [], array $responseCookies = [])
205205
{
206206
if (isset($responseBodyArray['errors'])) {
207207
$errorMessage = '';
@@ -221,7 +221,11 @@ private function processErrors($responseBodyArray)
221221

222222
throw new ResponseContainsErrorsException(
223223
'GraphQL response contains errors: ' . $errorMessage,
224-
$responseBodyArray
224+
$responseBodyArray,
225+
null,
226+
0,
227+
$responseHeaders,
228+
$responseCookies
225229
);
226230
}
227231
//phpcs:ignore Magento2.Exceptions.DirectThrow

dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/ResponseContainsErrorsException.php

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,34 @@ class ResponseContainsErrorsException extends \Exception
1717
*/
1818
private $responseData;
1919

20+
/**
21+
* @var array
22+
*/
23+
private $responseHeaders;
24+
25+
/**
26+
* @var array
27+
*/
28+
private $responseCookies;
29+
2030
/**
2131
* @param string $message
2232
* @param array $responseData
2333
* @param \Exception|null $cause
2434
* @param int $code
2535
*/
26-
public function __construct(string $message, array $responseData, \Exception $cause = null, int $code = 0)
27-
{
36+
public function __construct(
37+
string $message,
38+
array $responseData,
39+
\Exception $cause = null,
40+
int $code = 0,
41+
array $responseHeaders = [],
42+
array $responseCookies = []
43+
) {
2844
parent::__construct($message, $code, $cause);
2945
$this->responseData = $responseData;
46+
$this->responseHeaders = $responseHeaders;
47+
$this->responseCookies = $responseCookies;
3048
}
3149

3250
/**
@@ -38,4 +56,24 @@ public function getResponseData(): array
3856
{
3957
return $this->responseData;
4058
}
59+
60+
/**
61+
* Get response headers
62+
*
63+
* @return array
64+
*/
65+
public function getResponseHeaders(): array
66+
{
67+
return $this->responseHeaders;
68+
}
69+
70+
/**
71+
* Get response cookies
72+
*
73+
* @return array
74+
*/
75+
public function getResponseCookies(): array
76+
{
77+
return $this->responseCookies;
78+
}
4179
}

dev/tests/api-functional/testsuite/Magento/GraphQl/Eav/CustomAttributesMetadataCacheTest.php

Lines changed: 112 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
use Magento\TestFramework\Helper\Bootstrap;
1414
use Magento\TestFramework\TestCase\GraphQl\ResponseContainsErrorsException;
1515

16+
/**
17+
* Test caching for custom attribute metadata GraphQL query.
18+
*/
1619
class CustomAttributesMetadataCacheTest extends GraphQLPageCacheAbstract
1720
{
1821
/**
@@ -203,10 +206,57 @@ public function testCacheInvalidationOnAttributeDelete()
203206
$eavAttributeRepo = $this->objectManager->get(AttributeRepository::class);
204207
$attribute = $eavAttributeRepo->get("catalog_product", "dropdown_attribute");
205208
$eavAttributeRepo->delete($attribute);
209+
$this->assertQueryResultIsCacheMissWithError(
210+
$query,
211+
"GraphQL response contains errors: Internal server error"
212+
);
213+
}
214+
215+
/**
216+
* @magentoApiDataFixture Magento/Catalog/_files/dropdown_attribute.php
217+
* @magentoConfigFixture default/system/full_page_cache/caching_application 2
218+
*
219+
* @return void
220+
*/
221+
public function testCacheMissingAttributeParam()
222+
{
223+
$query = $this->getAttributeQueryNoCode("catalog_product");
224+
// check cache missed on each query
225+
$this->assertQueryResultIsCacheMissWithError(
226+
$query,
227+
"Missing attribute_code for the input entity_type: catalog_product."
228+
);
229+
$this->assertQueryResultIsCacheMissWithError(
230+
$query,
231+
"Missing attribute_code for the input entity_type: catalog_product."
232+
);
233+
234+
$query = $this->getAttributeQueryNoEntityType("dropdown_attribute");
235+
// check cache missed on each query
236+
$this->assertQueryResultIsCacheMissWithError(
237+
$query,
238+
"Missing entity_type for the input attribute_code: dropdown_attribute."
239+
);
240+
$this->assertQueryResultIsCacheMissWithError(
241+
$query,
242+
"Missing entity_type for the input attribute_code: dropdown_attribute."
243+
);
244+
}
245+
246+
/**
247+
* Assert that query produces an error and the cache is missed.
248+
*
249+
* @param string $query
250+
* @param string $expectedError
251+
* @return void
252+
* @throws \Exception
253+
*/
254+
private function assertQueryResultIsCacheMissWithError(string $query, string $expectedError)
255+
{
206256
$caughtException = null;
207257
try {
208-
// get response
209-
$response = $this->graphQlQuery($query, []);
258+
// query for response, expect response to be present in exception
259+
$this->graphQlQueryWithResponseHeaders($query, []);
210260
} catch (ResponseContainsErrorsException $exception) {
211261
$caughtException = $exception;
212262
}
@@ -216,12 +266,12 @@ public function testCacheInvalidationOnAttributeDelete()
216266
);
217267
// cannot use expectException because need to assert the headers
218268
$this->assertStringContainsString(
219-
"GraphQL response contains errors: Internal server error",
269+
$expectedError,
220270
$caughtException->getMessage()
221271
);
222272
// assert that it's a miss after deletion
223273
$this->assertEquals(
224-
$response['headers']['X-Magento-Cache-Debug'],
274+
$caughtException->getResponseHeaders()['X-Magento-Cache-Debug'],
225275
'MISS'
226276
);
227277
}
@@ -282,6 +332,64 @@ private function getAttributeQuery(string $code, string $entityType) : string
282332
}
283333
}
284334
}
335+
QUERY;
336+
}
337+
338+
/**
339+
* Prepare and return GraphQL query for given entity type with no code.
340+
*
341+
* @param string $code
342+
* @param string $entityType
343+
* @return string
344+
*/
345+
private function getAttributeQueryNoCode(string $entityType) : string
346+
{
347+
return <<<QUERY
348+
{
349+
customAttributeMetadata(attributes:
350+
[
351+
{
352+
entity_type:"{$entityType}"
353+
}
354+
]
355+
)
356+
{
357+
items
358+
{
359+
attribute_code
360+
entity_type
361+
}
362+
}
363+
}
364+
QUERY;
365+
}
366+
367+
/**
368+
* Prepare and return GraphQL query for given code with no entity type.
369+
*
370+
* @param string $code
371+
* @param string $entityType
372+
* @return string
373+
*/
374+
private function getAttributeQueryNoEntityType(string $code) : string
375+
{
376+
return <<<QUERY
377+
{
378+
customAttributeMetadata(attributes:
379+
[
380+
{
381+
attribute_code:"{$code}"
382+
}
383+
]
384+
)
385+
{
386+
items
387+
{
388+
attribute_code
389+
entity_type
390+
}
391+
}
392+
}
285393
QUERY;
286394
}
287395
}

0 commit comments

Comments
 (0)