Skip to content

Commit ffe0e8f

Browse files
committed
B2B-2258: Add caching capability to the storeConfig GraphQl query
1 parent c143fb4 commit ffe0e8f

File tree

4 files changed

+217
-3
lines changed

4 files changed

+217
-3
lines changed

app/code/Magento/StoreGraphQl/Model/Cache/Tag/Strategy/StoreConfig.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,28 @@
99

1010
use Magento\Framework\App\Cache\Tag\StrategyInterface;
1111
use Magento\Framework\App\Config\ValueInterface;
12+
use Magento\Store\Model\ScopeInterface;
13+
use Magento\Store\Model\StoreManagerInterface;
1214
use Magento\StoreGraphQl\Model\Resolver\Store\ConfigIdentity;
1315

1416
/**
1517
* Produce cache tags for store config.
1618
*/
1719
class StoreConfig implements StrategyInterface
1820
{
21+
/**
22+
* @var StoreManagerInterface
23+
*/
24+
private $storeManager;
25+
26+
/**
27+
* @param StoreManagerInterface $storeManager
28+
*/
29+
public function __construct(
30+
StoreManagerInterface $storeManager
31+
) {
32+
$this->storeManager = $storeManager;
33+
}
1934
/**
2035
* @inheritdoc
2136
*/
@@ -26,7 +41,19 @@ public function getTags($object): array
2641
}
2742

2843
if ($object instanceof ValueInterface && $object->isValueChanged()) {
29-
return [ConfigIdentity::CACHE_TAG];
44+
if ($object->getScope() == ScopeInterface::SCOPE_WEBSITES) {
45+
$website = $this->storeManager->getWebsite($object->getScopeId());
46+
$storeIds = $website->getStoreIds();
47+
} elseif ($object->getScope() == ScopeInterface::SCOPE_STORES) {
48+
$storeIds = [$object->getScopeId()];
49+
} else {
50+
$storeIds = array_keys($this->storeManager->getStores());
51+
}
52+
$ids = [];
53+
foreach ($storeIds as $storeId) {
54+
$ids[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, $storeId);
55+
}
56+
return $ids;
3057
}
3158

3259
return [];

app/code/Magento/StoreGraphQl/Model/Resolver/Store/ConfigIdentity.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ class ConfigIdentity implements IdentityInterface
2121
*/
2222
public function getIdentities(array $resolvedData): array
2323
{
24-
return empty($resolvedData) ? [] : [self::CACHE_TAG];
24+
$data["id"] = empty($resolvedData) ? [] : $resolvedData["id"];
25+
$ids = empty($resolvedData) ?
26+
[] : array_merge([self::CACHE_TAG], array_map(function ($key) {
27+
return sprintf('%s_%s', self::CACHE_TAG, $key);
28+
}, $data));
29+
return $ids;
2530
}
2631
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ protected function assertResponseFields($actualResponse, $assertionMap)
208208
}
209209

210210
/**
211-
* Flush page cache
211+
* Tear down test and flush page cache
212212
*
213213
* @return void
214214
*/
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GraphQl\Store;
9+
10+
use Magento\Framework\Exception\NoSuchEntityException;
11+
use Magento\Store\Api\Data\StoreConfigInterface;
12+
use Magento\Store\Api\StoreConfigManagerInterface;
13+
use Magento\Store\Api\StoreRepositoryInterface;
14+
use Magento\Store\Api\StoreResolverInterface;
15+
use Magento\Store\Model\ScopeInterface;
16+
use Magento\TestFramework\Helper\Bootstrap;
17+
use Magento\TestFramework\ObjectManager;
18+
use Magento\TestFramework\TestCase\GraphQlAbstract;
19+
20+
/**
21+
* Test storeConfig query cache
22+
*/
23+
class StoreConfigCacheTest extends GraphQlAbstract
24+
{
25+
26+
/** @var ObjectManager */
27+
private $objectManager;
28+
29+
/**
30+
* @inheritDoc
31+
*/
32+
protected function setUp(): void
33+
{
34+
$this->objectManager = Bootstrap::getObjectManager();
35+
}
36+
37+
/**
38+
* @magentoApiDataFixture Magento/Store/_files/store.php
39+
* @throws NoSuchEntityException
40+
*/
41+
public function testGetStoreConfig(): void
42+
{
43+
/** @var StoreConfigManagerInterface $storeConfigManager */
44+
$storeConfigManager = $this->objectManager->get(StoreConfigManagerInterface::class);
45+
/** @var StoreResolverInterface $storeResolver */
46+
$storeResolver = $this->objectManager->get(StoreResolverInterface::class);
47+
/** @var StoreRepositoryInterface $storeRepository */
48+
$storeRepository = $this->objectManager->get(StoreRepositoryInterface::class);
49+
$storeId = $storeResolver->getCurrentStoreId();
50+
$store = $storeRepository->getById($storeId);
51+
/** @var StoreConfigInterface $storeConfig */
52+
$storeConfig = current($storeConfigManager->getStoreConfigs([$store->getCode()]));
53+
$defaultLocale = $storeConfig->getLocale();
54+
$query = $this->getQuery();
55+
56+
// Query default store config
57+
$response = $this->graphQlQueryWithResponseHeaders($query);
58+
$this->assertArrayHasKey('X-Magento-Cache-Debug', $response['headers']);
59+
$this->assertEquals('MISS', $response['headers']['X-Magento-Cache-Debug']);
60+
$this->assertArrayHasKey('storeConfig', $response['body']);
61+
$responseConfig = $response['body']['storeConfig'];
62+
$this->assertEquals($storeConfig->getId(), $responseConfig['id']);
63+
$this->assertEquals($storeConfig->getCode(), $responseConfig['code']);
64+
$this->assertEquals($defaultLocale, $responseConfig['locale']);
65+
// Query default store config again
66+
$responseHit = $this->graphQlQueryWithResponseHeaders($query);
67+
$this->assertArrayHasKey('X-Magento-Cache-Debug', $responseHit['headers']);
68+
$this->assertEquals('HIT', $responseHit['headers']['X-Magento-Cache-Debug']);
69+
$responseHitConfig = $responseHit['body']['storeConfig'];
70+
$this->assertEquals($storeConfig->getCode(), $responseHitConfig['code']);
71+
$this->assertEquals($defaultLocale, $responseHitConfig['locale']);
72+
73+
// Query test store config
74+
$headerMap['Store'] = 'test';
75+
$responseTestStore = $this->graphQlQueryWithResponseHeaders($query, [], '', $headerMap);
76+
$this->assertArrayHasKey('X-Magento-Cache-Debug', $responseTestStore['headers']);
77+
$this->assertEquals('MISS', $responseTestStore['headers']['X-Magento-Cache-Debug']);
78+
$responseTestStoreConfig = $responseTestStore['body']['storeConfig'];
79+
$this->assertEquals('test', $responseTestStoreConfig['code']);
80+
$this->assertEquals($defaultLocale, $responseTestStoreConfig['locale']);
81+
// Query test store config again
82+
$responseTestStoreHit = $this->graphQlQueryWithResponseHeaders($query, [], '', $headerMap);
83+
$this->assertArrayHasKey('X-Magento-Cache-Debug', $responseTestStoreHit['headers']);
84+
$this->assertEquals('HIT', $responseTestStoreHit['headers']['X-Magento-Cache-Debug']);
85+
$responseTestStoreHitConfig = $responseTestStoreHit['body']['storeConfig'];
86+
$this->assertEquals('test', $responseTestStoreHitConfig['code']);
87+
$this->assertEquals($defaultLocale, $responseTestStoreHitConfig['locale']);
88+
89+
// Change test store locale
90+
$newLocale = 'de_DE';
91+
$this->setConfig('general/locale/code', $newLocale, ScopeInterface::SCOPE_STORES, 'test');
92+
93+
// Query default store config
94+
$responseHit2 = $this->graphQlQueryWithResponseHeaders($query);
95+
$this->assertArrayHasKey('X-Magento-Cache-Debug', $responseHit2['headers']);
96+
$this->assertEquals('HIT', $responseHit2['headers']['X-Magento-Cache-Debug']);
97+
$responseHit2Config = $responseHit2['body']['storeConfig'];
98+
$this->assertEquals($storeConfig->getCode(), $responseHit2Config['code']);
99+
$this->assertEquals($defaultLocale, $responseHit2Config['locale']);
100+
101+
// Query test store config
102+
$responseTestStoreMiss = $this->graphQlQueryWithResponseHeaders($query, [], '', $headerMap);
103+
$this->assertArrayHasKey('X-Magento-Cache-Debug', $responseTestStoreMiss['headers']);
104+
$this->assertEquals('MISS', $responseTestStoreMiss['headers']['X-Magento-Cache-Debug']);
105+
$responseTestStoreMissConfig = $responseTestStoreMiss['body']['storeConfig'];
106+
$this->assertEquals('test', $responseTestStoreMissConfig['code']);
107+
$this->assertEquals($newLocale, $responseTestStoreMissConfig['locale']);
108+
109+
// Query test store config again
110+
$responseTestStoreHit2 = $this->graphQlQueryWithResponseHeaders($query, [], '', $headerMap);
111+
$this->assertArrayHasKey('X-Magento-Cache-Debug', $responseTestStoreHit2['headers']);
112+
$this->assertEquals('HIT', $responseTestStoreHit2['headers']['X-Magento-Cache-Debug']);
113+
$responseTestStoreHit2Config = $responseTestStoreHit2['body']['storeConfig'];
114+
$this->assertEquals('test', $responseTestStoreHit2Config['code']);
115+
$this->assertEquals($newLocale, $responseTestStoreHit2Config['locale']);
116+
}
117+
118+
/**
119+
* Get query
120+
*
121+
* @return string
122+
*/
123+
private function getQuery(): string
124+
{
125+
$query
126+
= <<<QUERY
127+
{
128+
storeConfig {
129+
id,
130+
code,
131+
store_code,
132+
store_name,
133+
store_sort_order,
134+
is_default_store,
135+
store_group_code,
136+
store_group_name,
137+
is_default_store_group,
138+
website_id,
139+
website_code,
140+
website_name,
141+
locale,
142+
base_currency_code,
143+
default_display_currency_code,
144+
timezone,
145+
weight_unit,
146+
base_url,
147+
base_link_url,
148+
base_static_url,
149+
base_media_url,
150+
secure_base_url,
151+
secure_base_link_url,
152+
secure_base_static_url,
153+
secure_base_media_url,
154+
store_name
155+
}
156+
}
157+
QUERY;
158+
return $query;
159+
}
160+
161+
/**
162+
* Set configuration
163+
*
164+
* @param string $path
165+
* @param string $value
166+
* @param string|null $scope
167+
* @param string|null $scopeCode
168+
* @return void
169+
* @throws \Magento\Framework\Exception\LocalizedException
170+
*/
171+
private function setConfig(string $path, string $value, ?string $scope = null, ?string $scopeCode = null) : void
172+
{
173+
$options = '';
174+
$options .= $scope ? "--scope=$scope " : '';
175+
$options .= $scopeCode ? "--scope-code=$scopeCode " : '';
176+
$options .= "$path $value";
177+
$appDir = dirname(Bootstrap::getInstance()->getAppTempDir());
178+
$out = '';
179+
// phpcs:ignore Magento2.Security.InsecureFunction
180+
exec("php -f {$appDir}/bin/magento config:set $options", $out);
181+
}
182+
}

0 commit comments

Comments
 (0)