Skip to content

Commit de44f2a

Browse files
committed
ACP2E-3096: Incorrect curl headers making newrelic:create:deploy-marker not working
1 parent 60c6de1 commit de44f2a

File tree

2 files changed

+141
-12
lines changed

2 files changed

+141
-12
lines changed

lib/internal/Magento/Framework/HTTP/Test/Unit/Adapter/CurlTest.php

Lines changed: 126 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Magento\Framework\HTTP\Test\Unit\Adapter;
99

1010
use Magento\Framework\HTTP\Adapter\Curl;
11+
use PHPUnit\Framework\MockObject\MockObject;
1112
use PHPUnit\Framework\TestCase;
1213

1314
class CurlTest extends TestCase
@@ -18,39 +19,153 @@ class CurlTest extends TestCase
1819
protected $model;
1920

2021
/**
21-
* @var \Closure
22+
* @var MockObject|\StdClass
2223
*/
23-
public static $curlExectClosure;
24+
public static $curlMock;
2425

2526
protected function setUp(): void
2627
{
28+
self::$curlMock = $this->getMockBuilder(\StdClass::class)
29+
->addMethods(['setopt', 'exec'])
30+
->getMock();
2731
require_once __DIR__ . '/_files/curl_exec_mock.php';
2832
$this->model = new Curl();
2933
}
3034

35+
protected function tearDown(): void
36+
{
37+
self::$curlMock = null;
38+
}
39+
3140
/**
3241
* @param string $response
3342
* @dataProvider readDataProvider
3443
*/
3544
public function testRead($response)
3645
{
37-
self::$curlExectClosure = function () use ($response) {
38-
return $response;
39-
};
46+
self::$curlMock->expects($this->once())
47+
->method('exec')
48+
->willReturn($response);
4049
$this->assertEquals(file_get_contents(__DIR__ . '/_files/curl_response_expected.txt'), $this->model->read());
4150
}
4251

43-
/**
44-
* @param string $response
45-
*/
4652
public function testReadFailure()
4753
{
48-
self::$curlExectClosure = function () {
49-
return false;
50-
};
54+
self::$curlMock->expects($this->once())
55+
->method('exec')
56+
->willReturn(false);
5157
$this->assertEquals('', $this->model->read());
5258
}
5359

60+
/**
61+
* @param string $method
62+
* @param string $url
63+
* @param string $http_ver
64+
* @param array $headers
65+
* @param string $body
66+
* @param array $setopt
67+
* @return void
68+
* @dataProvider writeDataProvider
69+
*/
70+
public function testWrite(
71+
string $method,
72+
string $url,
73+
string $http_ver,
74+
array $headers,
75+
string $body,
76+
array $setopt
77+
): void {
78+
$defaultConfig = [];
79+
$configKeyToCurlProp = (new \ReflectionProperty(Curl::class, '_allowedParams'))->getValue($this->model);
80+
foreach ((new \ReflectionProperty(Curl::class, '_config'))->getValue($this->model) as $key => $value) {
81+
if (isset($configKeyToCurlProp[$key])) {
82+
$defaultConfig[] = [$configKeyToCurlProp[$key], $value];
83+
}
84+
}
85+
$setopt = array_merge(
86+
$defaultConfig,
87+
[
88+
[CURLOPT_URL, $url],
89+
[CURLOPT_RETURNTRANSFER, true],
90+
],
91+
$setopt,
92+
[
93+
[CURLOPT_HEADER, true],
94+
]
95+
);
96+
self::$curlMock->expects($this->exactly(count($setopt)))
97+
->method('setopt')
98+
->with(
99+
$this->isInstanceOf(\CurlHandle::class),
100+
$this->callback(
101+
function (int $opt) use ($setopt) {
102+
static $it = 0;
103+
return $opt === $setopt[$it++][0];
104+
}
105+
),
106+
$this->callback(
107+
function (mixed $val) use ($setopt) {
108+
static $it = 0;
109+
return $val === $setopt[$it++][1];
110+
}
111+
)
112+
)
113+
->willReturn(true);
114+
115+
$this->model->write($method, $url, $http_ver, $headers, $body);
116+
}
117+
118+
/**
119+
* @return array
120+
*/
121+
public function writeDataProvider()
122+
{
123+
return [
124+
'headers is empty' => [
125+
'POST',
126+
'http://example.com',
127+
'1.1',
128+
[],
129+
'{"key": "value"}',
130+
[
131+
[CURLOPT_POST, true],
132+
[CURLOPT_CUSTOMREQUEST, 'POST'],
133+
[CURLOPT_POSTFIELDS, '{"key": "value"}'],
134+
[CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1],
135+
[CURLOPT_HTTPHEADER, []],
136+
]
137+
],
138+
'headers is an indexed array' => [
139+
'POST',
140+
'http://example.com',
141+
'1.1',
142+
['Content-Type: application/json'],
143+
'{"key": "value"}',
144+
[
145+
[CURLOPT_POST, true],
146+
[CURLOPT_CUSTOMREQUEST, 'POST'],
147+
[CURLOPT_POSTFIELDS, '{"key": "value"}'],
148+
[CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1],
149+
[CURLOPT_HTTPHEADER, ['Content-Type: application/json']],
150+
]
151+
],
152+
'headers is an associative array' => [
153+
'POST',
154+
'http://example.com',
155+
'1.1',
156+
['Content-Type' => 'application/json'],
157+
'{"key": "value"}',
158+
[
159+
[CURLOPT_POST, true],
160+
[CURLOPT_CUSTOMREQUEST, 'POST'],
161+
[CURLOPT_POSTFIELDS, '{"key": "value"}'],
162+
[CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1],
163+
[CURLOPT_HTTPHEADER, ['Content-Type: application/json']],
164+
]
165+
],
166+
];
167+
}
168+
54169
/**
55170
* @return array
56171
*/

lib/internal/Magento/Framework/HTTP/Test/Unit/Adapter/_files/curl_exec_mock.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,19 @@
1818
*/
1919
function curl_exec($resource)
2020
{
21-
return call_user_func(CurlTest::$curlExectClosure);
21+
return CurlTest::$curlMock->exec($resource);
22+
}
23+
24+
/**
25+
* Override global PHP function curl_setopt
26+
*
27+
* @param mixed $handle
28+
* @param int $option
29+
* @param mixed $value
30+
* @return bool
31+
* @see \curl_setopt()
32+
*/
33+
function curl_setopt(mixed $handle, int $option, mixed $value): bool
34+
{
35+
return CurlTest::$curlMock->setopt($handle, $option, $value);
2236
}

0 commit comments

Comments
 (0)