Skip to content

Commit 8f06e91

Browse files
authored
Merge pull request #7591 from magento-arcticfoxes/B2B-2204
B2B-2204: Implement Toggle For Enabling/Disabling Session Support for…
2 parents 9058428 + ad11a22 commit 8f06e91

File tree

11 files changed

+683
-40
lines changed

11 files changed

+683
-40
lines changed

app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class CurrencyProcessor implements HttpHeaderProcessorInterface
3030

3131
/**
3232
* @var SessionManagerInterface
33+
* @deprecated
3334
*/
3435
private $session;
3536

@@ -65,37 +66,21 @@ public function __construct(
6566
public function processHeaderValue(string $headerValue) : void
6667
{
6768
try {
68-
if (!empty($headerValue)) {
69-
$headerCurrency = strtoupper(ltrim(rtrim($headerValue)));
70-
/** @var \Magento\Store\Model\Store $currentStore */
71-
$currentStore = $this->storeManager->getStore();
72-
if (in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes(true))) {
73-
$currentStore->setCurrentCurrencyCode($headerCurrency);
74-
} else {
75-
/** @var \Magento\Store\Model\Store $store */
76-
$store = $this->storeManager->getStore() ?? $this->storeManager->getDefaultStoreView();
77-
//skip store not found exception as it will be handled in graphql validation
78-
$this->logger->warning(__('Currency not allowed for store %1', [$store->getCode()]));
79-
$this->httpContext->setValue(
80-
HttpContext::CONTEXT_CURRENCY,
81-
$headerCurrency,
82-
$store->getDefaultCurrency()->getCode()
83-
);
84-
}
69+
$currentStore = $this->storeManager->getStore();
70+
$defaultCode = $currentStore->getDefaultCurrency()->getCode();
71+
if (empty($headerValue)) {
72+
$this->httpContext->setValue(
73+
HttpContext::CONTEXT_CURRENCY,
74+
$currentStore->getCurrentCurrency()->getCode(),
75+
$defaultCode
76+
);
8577
} else {
86-
if ($this->session->getCurrencyCode()) {
87-
/** @var \Magento\Store\Model\Store $currentStore */
88-
$currentStore = $this->storeManager->getStore() ?? $this->storeManager->getDefaultStoreView();
89-
$currentStore->setCurrentCurrencyCode($this->session->getCurrencyCode());
90-
} else {
91-
/** @var \Magento\Store\Model\Store $store */
92-
$store = $this->storeManager->getStore() ?? $this->storeManager->getDefaultStoreView();
93-
$this->httpContext->setValue(
94-
HttpContext::CONTEXT_CURRENCY,
95-
$store->getCurrentCurrency()->getCode(),
96-
$store->getDefaultCurrency()->getCode()
97-
);
78+
$headerCurrency = strtoupper(trim($headerValue));
79+
if (!in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes(true))) {
80+
//skip store not found exception as it will be handled in graphql validation
81+
$this->logger->warning(__('Currency not allowed for store %1', [$currentStore->getCode()]));
9882
}
83+
$this->httpContext->setValue(HttpContext::CONTEXT_CURRENCY, $headerCurrency, $defaultCode);
9984
}
10085
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
10186
//skip store not found exception as it will be handled in graphql validation
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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\Model\Config;
9+
10+
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
12+
/**
13+
* Session disable in graphql configuration model.
14+
*/
15+
class DisableSession
16+
{
17+
private const XML_PATH_GRAPHQL_DISABLE_SESSION = 'graphql/session/disable';
18+
19+
/**
20+
* @var ScopeConfigInterface
21+
*/
22+
private $scopeConfig;
23+
24+
/**
25+
* @param ScopeConfigInterface $scopeConfig
26+
*/
27+
public function __construct(ScopeConfigInterface $scopeConfig)
28+
{
29+
$this->scopeConfig = $scopeConfig;
30+
}
31+
32+
/**
33+
* Get config value is session disabled for grapqhl area.
34+
*
35+
* @param string $scopeType
36+
* @param null|int|string $scopeCode
37+
* @return bool
38+
*/
39+
public function isDisabled($scopeType = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $scopeCode = null): bool
40+
{
41+
$value = $this->scopeConfig->getValue(
42+
self::XML_PATH_GRAPHQL_DISABLE_SESSION,
43+
$scopeType,
44+
$scopeCode
45+
);
46+
47+
if ($value === '1') {
48+
return true;
49+
}
50+
51+
return false;
52+
}
53+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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\Plugin;
9+
10+
use Magento\Framework\App\Area;
11+
use Magento\Framework\App\State;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\Session\SessionStartChecker;
14+
use Magento\GraphQl\Model\Config\DisableSession as DisableSessionConfig;
15+
16+
/**
17+
* Disable session in graphql area if configured.
18+
*/
19+
class DisableSession
20+
{
21+
/**
22+
* @var DisableSessionConfig
23+
*/
24+
private $disableSessionConfig;
25+
26+
/**
27+
* @var State
28+
*/
29+
private $appState;
30+
31+
/**
32+
* @param DisableSessionConfig $disableSessionConfig
33+
* @param State $appState
34+
*/
35+
public function __construct(
36+
DisableSessionConfig $disableSessionConfig,
37+
State $appState
38+
) {
39+
$this->disableSessionConfig = $disableSessionConfig;
40+
$this->appState = $appState;
41+
}
42+
43+
/**
44+
* Prevents session starting while in graphql area and session is disabled in config.
45+
*
46+
* @param SessionStartChecker $subject
47+
* @param bool $result
48+
* @return bool
49+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
50+
* @SuppressWarnings(PHPMD.EmptyCatchBlock)
51+
*/
52+
public function afterCheck(SessionStartChecker $subject, bool $result): bool
53+
{
54+
if (!$result) {
55+
return false;
56+
}
57+
try {
58+
if ($this->appState->getAreaCode() === Area::AREA_GRAPHQL && $this->disableSessionConfig->isDisabled()) {
59+
$result = false;
60+
}
61+
} catch (LocalizedException $e) {} finally { //@codingStandardsIgnoreLine
62+
return $result;
63+
}
64+
}
65+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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\Test\Unit\Model\Config;
9+
10+
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
12+
use Magento\GraphQl\Model\Config\DisableSession;
13+
use PHPUnit\Framework\MockObject\MockObject;
14+
use PHPUnit\Framework\TestCase;
15+
16+
/**
17+
* Test for DisableSession config model.
18+
*/
19+
class DisableSessionTest extends TestCase
20+
{
21+
/**
22+
* @var ScopeConfigInterface|MockObject
23+
*/
24+
private $scopeConfigMock;
25+
26+
/**
27+
* @var DisableSession
28+
*/
29+
private $model;
30+
31+
/**
32+
* @inheirtDoc
33+
*/
34+
public function setUp(): void
35+
{
36+
$this->scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class);
37+
$this->model = (new ObjectManager($this))->getObject(
38+
DisableSession::class,
39+
['scopeConfig' => $this->scopeConfigMock]
40+
);
41+
}
42+
43+
/**
44+
* @dataProvider disableSessionDataProvider
45+
*/
46+
public function testisSessionDisabled($configValue, $expectedResult)
47+
{
48+
$this->scopeConfigMock->expects($this->any())->method('getValue')->willReturn($configValue);
49+
$this->assertEquals($expectedResult, $this->model->isDisabled());
50+
}
51+
52+
/**
53+
* Data provider for session disabled config test.
54+
* @return array[]
55+
*/
56+
public function disableSessionDataProvider()
57+
{
58+
return [
59+
['configValue' => '1', true],
60+
['configValue' => '0', false],
61+
['configValue' => '11', false],
62+
['configValue' => null, false],
63+
['configValue' => '', false],
64+
['configValue' => 'adfjsadf', false],
65+
];
66+
}
67+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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\Test\Unit\Plugin;
9+
10+
use Magento\Framework\App\State;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\Session\SessionStartChecker;
13+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
14+
use Magento\GraphQl\Model\Config\DisableSession;
15+
use Magento\GraphQl\Plugin\DisableSession as DisableSessionPlugin;
16+
use PHPUnit\Framework\MockObject\MockObject;
17+
use PHPUnit\Framework\TestCase;
18+
19+
/**
20+
* Test for DisableSession plugin.
21+
*/
22+
class DisableSessionTest extends TestCase
23+
{
24+
/**
25+
* @var DisableSession|MockObject
26+
*/
27+
private $disableSessionConfigMock;
28+
29+
/**
30+
* @var State|MockObject
31+
*/
32+
private $appStateMock;
33+
34+
/**
35+
* @var DisableSessionPlugin
36+
*/
37+
private $model;
38+
39+
/**
40+
* @var SessionStartChecker|MockObject
41+
*/
42+
private $sessionStartCheckerMock;
43+
44+
public function setUp(): void
45+
{
46+
$this->disableSessionConfigMock = $this->createMock(DisableSession::class);
47+
$this->appStateMock = $this->createMock(State::class);
48+
$this->sessionStartCheckerMock = $this->createMock(SessionStartChecker::class);
49+
$this->model = (new ObjectManager($this))->getObject(
50+
DisableSessionPlugin::class,
51+
[
52+
'disableSessionConfig' => $this->disableSessionConfigMock,
53+
'appState' => $this->appStateMock
54+
]
55+
);
56+
}
57+
58+
/**
59+
* Test afterCheck plugin result over original method result.
60+
*
61+
* @param string $area
62+
* @param bool $config
63+
* @param bool $methodResult
64+
* @param bool $expectedResult
65+
* @return void
66+
* @dataProvider testAfterCheckDataProvider
67+
*/
68+
public function testAfterCheck(string $area, bool $config, bool $methodResult, bool $expectedResult)
69+
{
70+
$this->disableSessionConfigMock->expects($this->any())->method('isDisabled')->willReturn($config);
71+
$this->appStateMock->expects($this->any())->method('getAreaCode')->willReturn($area);
72+
$this->assertEquals($expectedResult, $this->model->afterCheck($this->sessionStartCheckerMock, $methodResult));
73+
}
74+
75+
/**
76+
* Data provider for testAfterCheck.
77+
*
78+
* @return array[]
79+
*/
80+
public function testAfterCheckDataProvider()
81+
{
82+
return [
83+
['area' => 'graphql', 'config' => true, 'methodResult' => false, 'expected' => false],
84+
['area' => 'graphql', 'config' => true, 'methodResult' => true, 'expected' => false],
85+
['area' => 'graphql', 'config' => false, 'methodResult' => true, 'expected' => true],
86+
['area' => 'graphql', 'config' => false, 'methodResult' => false, 'expected' => false],
87+
['area' => 'other', 'config' => false, 'methodResult' => false, 'expected' => false],
88+
['area' => 'other', 'config' => true, 'methodResult' => false, 'expected' => false],
89+
['area' => 'other', 'config' => true, 'methodResult' => true, 'expected' => true],
90+
['area' => 'other', 'config' => false, 'methodResult' => true, 'expected' => true],
91+
];
92+
}
93+
94+
/**
95+
* Test afterCheck plugin result over original method result when no area code set.
96+
*
97+
* @param bool $config
98+
* @param bool $methodResult
99+
* @param bool $expectedResult
100+
* @return void
101+
* @dataProvider testAfterCheckDataProviderNoAreaCode
102+
*/
103+
public function testAfterCheckNoArea(bool $config, bool $methodResult, bool $expectedResult)
104+
{
105+
$this->disableSessionConfigMock->expects($this->any())->method('isDisabled')->willReturn($config);
106+
$this->appStateMock->expects($this->any())
107+
->method('getAreaCode')
108+
->willThrowException(new LocalizedException(__('Are code not set')));
109+
$this->assertEquals($expectedResult, $this->model->afterCheck($this->sessionStartCheckerMock, $methodResult));
110+
}
111+
112+
/**
113+
* Data provider for testAfterCheck.
114+
*
115+
* @return array[]
116+
*/
117+
public function testAfterCheckDataProviderNoAreaCode()
118+
{
119+
return [
120+
['config' => true, 'methodResult' => true, 'expected' => true],
121+
['config' => true, 'methodResult' => false, 'expected' => false],
122+
['config' => false, 'methodResult' => true, 'expected' => true],
123+
['config' => false, 'methodResult' => false, 'expected' => false],
124+
];
125+
}
126+
}

app/code/Magento/GraphQl/etc/adminhtml/system.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626
</depends>
2727
</field>
2828
</group>
29+
<group id="graphql_session" translate="label" type="text" sortOrder="20" showInDefault="0" showInWebsite="0" showInStore="0">
30+
<label>GraphQl Session Management</label>
31+
<field id="disabled" translate="label" type="select" sortOrder="20" showInDefault="0" showInWebsite="0" showInStore="0">
32+
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
33+
<label>Disable session</label>
34+
<config_path>graphql/session/disable</config_path>
35+
</field>
36+
</group>
2937
</section>
3038
</system>
3139
</config>

0 commit comments

Comments
 (0)