Skip to content

Commit 3c857e1

Browse files
Merge pull request #8265 from magento-cia/cia-2.4.7-beta1-develop-bugfixes-04282023
cia-2.4.7-beta1-develop-bugfixes-04282023
2 parents caab350 + 1302c40 commit 3c857e1

File tree

8 files changed

+413
-0
lines changed

8 files changed

+413
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Fedex\Model\Config\Backend;
10+
11+
use Magento\Framework\App\Cache\TypeListInterface;
12+
use Magento\Framework\App\Config\ScopeConfigInterface;
13+
use Magento\Framework\App\Config\Value;
14+
use Magento\Framework\Data\Collection\AbstractDb;
15+
use Magento\Framework\Exception\ValidatorException;
16+
use Magento\Framework\Model\AbstractModel;
17+
use Magento\Framework\Model\Context;
18+
use Magento\Framework\Model\ResourceModel\AbstractResource;
19+
use Magento\Framework\Registry;
20+
use Magento\Framework\Validator\Url;
21+
22+
/**
23+
* Represents a config URL that may point to a Fedex endpoint
24+
*/
25+
class FedexUrl extends Value
26+
{
27+
/**
28+
* @var Url
29+
*/
30+
private Url $url;
31+
/**
32+
* @param Context $context
33+
* @param Registry $registry
34+
* @param ScopeConfigInterface $config
35+
* @param TypeListInterface $cacheTypeList
36+
* @param AbstractResource|null $resource
37+
* @param AbstractDb|null $resourceCollection
38+
* @param Url $url
39+
* @param array $data
40+
*/
41+
public function __construct(
42+
Context $context,
43+
Registry $registry,
44+
ScopeConfigInterface $config,
45+
TypeListInterface $cacheTypeList,
46+
AbstractResource $resource = null,
47+
AbstractDb $resourceCollection = null,
48+
Url $url,
49+
array $data = []
50+
) {
51+
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
52+
$this->url = $url;
53+
}
54+
55+
/**
56+
* @inheritDoc
57+
*
58+
* @return AbstractModel
59+
* @throws ValidatorException
60+
*/
61+
public function beforeSave(): AbstractModel
62+
{
63+
$isValid = $this->url->isValid($this->getValue(), ['http', 'https']);
64+
65+
if ($isValid) {
66+
// phpcs:ignore Magento2.Functions.DiscouragedFunction
67+
$host = parse_url((string)$this->getValue(), \PHP_URL_HOST);
68+
69+
if (!empty($host) && !preg_match('/(?:.+\.|^)fedex\.com$/i', $host)) {
70+
throw new ValidatorException(__('Fedex API endpoint URL\'s must use fedex.com'));
71+
}
72+
}
73+
74+
return parent::beforeSave();
75+
}
76+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Fedex\Test\Unit\Model\Config\Backend;
10+
11+
use Magento\Fedex\Model\Config\Backend\FedexUrl;
12+
use Magento\Framework\App\Cache\TypeListInterface;
13+
use Magento\Framework\App\Config\ScopeConfigInterface;
14+
use Magento\Framework\Data\Collection\AbstractDb;
15+
use Magento\Framework\Event\ManagerInterface;
16+
use Magento\Framework\Exception\ValidatorException;
17+
use Magento\Framework\Model\Context;
18+
use Magento\Framework\Registry;
19+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
20+
use Magento\Framework\Validator\Url;
21+
use Magento\Rule\Model\ResourceModel\AbstractResource;
22+
use PHPUnit\Framework\MockObject\MockObject;
23+
use PHPUnit\Framework\TestCase;
24+
25+
/**
26+
* Verify behavior of FedexUrl backend type
27+
*/
28+
class FedexUrlTest extends TestCase
29+
{
30+
31+
/**
32+
* @var FedexUrl
33+
*/
34+
private $urlConfig;
35+
36+
/**
37+
* @var Url
38+
*/
39+
private $url;
40+
41+
/**
42+
* @var Context|MockObject
43+
*/
44+
private $contextMock;
45+
46+
protected function setUp(): void
47+
{
48+
$objectManager = new ObjectManager($this);
49+
$this->contextMock = $this->createMock(Context::class);
50+
$registry = $this->createMock(Registry::class);
51+
$config = $this->createMock(ScopeConfigInterface::class);
52+
$cacheTypeList = $this->createMock(TypeListInterface::class);
53+
$this->url = $this->createMock(Url::class);
54+
$resource = $this->createMock(AbstractResource::class);
55+
$resourceCollection = $this->createMock(AbstractDb::class);
56+
$eventManagerMock = $this->getMockForAbstractClass(ManagerInterface::class);
57+
$eventManagerMock->expects($this->any())->method('dispatch');
58+
$this->contextMock->expects($this->any())->method('getEventDispatcher')->willReturn($eventManagerMock);
59+
60+
$this->urlConfig = $objectManager->getObject(
61+
FedexUrl::class,
62+
[
63+
'url' => $this->url,
64+
'context' => $this->contextMock,
65+
'registry' => $registry,
66+
'config' => $config,
67+
'cacheTypeList' => $cacheTypeList,
68+
'resource' => $resource,
69+
'resourceCollection' => $resourceCollection,
70+
]
71+
);
72+
}
73+
74+
/**
75+
* @dataProvider validDataProvider
76+
* @param string|null $data The valid data
77+
* @throws ValidatorException
78+
*/
79+
public function testBeforeSave(string $data = null): void
80+
{
81+
$this->url->expects($this->any())->method('isValid')->willReturn(true);
82+
$this->urlConfig->setValue($data);
83+
$this->urlConfig->beforeSave();
84+
$this->assertTrue($this->url->isValid($data));
85+
}
86+
87+
/**
88+
* @dataProvider invalidDataProvider
89+
* @param string $data The invalid data
90+
*/
91+
public function testBeforeSaveErrors(string $data): void
92+
{
93+
$this->url->expects($this->any())->method('isValid')->willReturn(true);
94+
$this->expectException('Magento\Framework\Exception\ValidatorException');
95+
$this->expectExceptionMessage('Fedex API endpoint URL\'s must use fedex.com');
96+
$this->urlConfig->setValue($data);
97+
$this->urlConfig->beforeSave();
98+
}
99+
100+
/**
101+
* Validator Data Provider
102+
*
103+
* @return array
104+
*/
105+
public function validDataProvider(): array
106+
{
107+
return [
108+
[],
109+
[null],
110+
[''],
111+
['http://fedex.com'],
112+
['https://foo.fedex.com'],
113+
['http://foo.fedex.com/foo/bar?baz=bash&fizz=buzz'],
114+
];
115+
}
116+
117+
/**
118+
* @return \string[][]
119+
*/
120+
public function invalidDataProvider(): array
121+
{
122+
return [
123+
['http://fedexfoo.com'],
124+
['https://foofedex.com'],
125+
['https://fedex.com.fake.com'],
126+
['https://fedex.info'],
127+
['http://fedex.com.foo.com/foo/bar?baz=bash&fizz=buzz'],
128+
['http://foofedex.com/foo/bar?baz=bash&fizz=buzz'],
129+
];
130+
}
131+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@
4040
</field>
4141
<field id="production_webservices_url" translate="label" type="text" sortOrder="90" showInDefault="1" showInWebsite="1" canRestore="1">
4242
<label>Web-Services URL (Production)</label>
43+
<backend_model>Magento\Fedex\Model\Config\Backend\FedexUrl</backend_model>
4344
<depends>
4445
<field id="sandbox_mode">0</field>
4546
</depends>
4647
</field>
4748
<field id="sandbox_webservices_url" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" canRestore="1">
4849
<label>Web-Services URL (Sandbox)</label>
50+
<backend_model>Magento\Fedex\Model\Config\Backend\FedexUrl</backend_model>
4951
<depends>
5052
<field id="sandbox_mode">1</field>
5153
</depends>

app/code/Magento/Fedex/i18n/en_US.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,4 @@ Debug,Debug
7878
"Show Method if Not Applicable","Show Method if Not Applicable"
7979
"Sort Order","Sort Order"
8080
"Can't convert a shipping cost from ""%1-%2"" for FedEx carrier.","Can't convert a shipping cost from ""%1-%2"" for FedEx carrier."
81+
"Fedex API endpoint URL\'s must use fedex.com","Fedex API endpoint URL\'s must use fedex.com"
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Usps\Model\Config\Backend;
10+
11+
use Magento\Framework\App\Cache\TypeListInterface;
12+
use Magento\Framework\App\Config\ScopeConfigInterface;
13+
use Magento\Framework\App\Config\Value;
14+
use Magento\Framework\Data\Collection\AbstractDb;
15+
use Magento\Framework\Exception\ValidatorException;
16+
use Magento\Framework\Model\Context;
17+
use Magento\Framework\Model\ResourceModel\AbstractResource;
18+
use Magento\Framework\Registry;
19+
use Magento\Framework\Validator\Url;
20+
21+
/**
22+
* Represents a config URL that may point to a USPS endpoint
23+
*
24+
* @SuppressWarnings(PHPMD.Superglobals)
25+
*/
26+
class UspsUrl extends Value
27+
{
28+
/**
29+
* @var Url
30+
*/
31+
private Url $url;
32+
33+
/**
34+
* @param Context $context
35+
* @param Registry $registry
36+
* @param ScopeConfigInterface $config
37+
* @param TypeListInterface $cacheTypeList
38+
* @param Url $url
39+
* @param AbstractResource|null $resource
40+
* @param AbstractDb|null $resourceCollection
41+
* @param array $data
42+
*/
43+
public function __construct(
44+
Context $context,
45+
Registry $registry,
46+
ScopeConfigInterface $config,
47+
TypeListInterface $cacheTypeList,
48+
Url $url,
49+
AbstractResource $resource = null,
50+
AbstractDb $resourceCollection = null,
51+
array $data = []
52+
) {
53+
$this->url = $url;
54+
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
55+
}
56+
57+
/**
58+
* @inheritdoc
59+
*
60+
* @throws ValidatorException
61+
*/
62+
public function beforeSave()
63+
{
64+
$isValid = $this->url->isValid($this->getValue());
65+
if ($isValid) {
66+
// phpcs:ignore Magento2.Functions.DiscouragedFunction
67+
$host = parse_url((string)$this->getValue(), \PHP_URL_HOST);
68+
69+
if (!empty($host) && !preg_match("/(?:.+\.|^)usps|shippingapis\.com$/i", $host)) {
70+
throw new ValidatorException(__('USPS API endpoint URL\'s must use usps.com or shippingapis.com'));
71+
}
72+
}
73+
74+
return parent::beforeSave();
75+
}
76+
}

0 commit comments

Comments
 (0)