Test for cookie strings and allow taking a $_SERVER variable in HttpRequest::fromRequest.
This commit is contained in:
parent
346b8a52e2
commit
d5b5efab46
4 changed files with 129 additions and 82 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
0.2503.80055
|
0.2503.82012
|
||||||
|
|
|
@ -31,7 +31,7 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
* @param string $method HTTP request method.
|
* @param string $method HTTP request method.
|
||||||
* @param HttpUri $uri HTTP request URI.
|
* @param HttpUri $uri HTTP request URI.
|
||||||
* @param array<string, list<?string>> $params HTTP request query parameters.
|
* @param array<string, list<?string>> $params HTTP request query parameters.
|
||||||
* @param array<string, string[]> $cookies HTTP request cookies.
|
* @param array<string, string> $cookies HTTP request cookies.
|
||||||
* @param array<string, array<object|string>>|object|null $parsedBody Parsed body contents.
|
* @param array<string, array<object|string>>|object|null $parsedBody Parsed body contents.
|
||||||
* @param ?array<string, HttpUploadedFile[]> $uploadedFiles Parsed files.
|
* @param ?array<string, HttpUploadedFile[]> $uploadedFiles Parsed files.
|
||||||
*/
|
*/
|
||||||
|
@ -110,7 +110,7 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
* @param ?string $method Value you'd otherwise pass to withMethod, null to leave unmodified.
|
* @param ?string $method Value you'd otherwise pass to withMethod, null to leave unmodified.
|
||||||
* @param ?UriInterface $uri Value you'd otherwise pass to withUri, null to leave unmodified.
|
* @param ?UriInterface $uri Value you'd otherwise pass to withUri, null to leave unmodified.
|
||||||
* @param ?array<string, list<?string>> $params Value you'd otherwise pass to withQueryParams, null to leave unmodified.
|
* @param ?array<string, list<?string>> $params Value you'd otherwise pass to withQueryParams, null to leave unmodified.
|
||||||
* @param ?array<string, string[]> $cookies Value you'd otherwise pass to withCookiesParams, null to leave unmodified.
|
* @param ?array<string, string> $cookies Value you'd otherwise pass to withCookiesParams, null to leave unmodified.
|
||||||
* @param null|array<string, string[]|object[]>|object|false $parsedBody Value you'd otherwise pass to withParsedBody, false to leave unmodified.
|
* @param null|array<string, string[]|object[]>|object|false $parsedBody Value you'd otherwise pass to withParsedBody, false to leave unmodified.
|
||||||
* @param array<string, HttpUploadedFile[]>|null|false $uploadedFiles Value you'd otherwise pass to withUploadedFiles, false to leave unmodified.
|
* @param array<string, HttpUploadedFile[]>|null|false $uploadedFiles Value you'd otherwise pass to withUploadedFiles, false to leave unmodified.
|
||||||
* @throws InvalidArgumentException If any of the arguments are not acceptable.
|
* @throws InvalidArgumentException If any of the arguments are not acceptable.
|
||||||
|
@ -210,14 +210,14 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<string, string[]>
|
* @return array<string, string>
|
||||||
*/
|
*/
|
||||||
public function getCookieParams(): array {
|
public function getCookieParams(): array {
|
||||||
return $this->cookies;
|
return $this->cookies;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, string[]> $cookies Array of key/value pairs representing cookies.
|
* @param array<string, string> $cookies Array of key/value pairs representing cookies.
|
||||||
*/
|
*/
|
||||||
public function withCookieParams(array $cookies): HttpRequest {
|
public function withCookieParams(array $cookies): HttpRequest {
|
||||||
return $this->with(cookies: $cookies);
|
return $this->with(cookies: $cookies);
|
||||||
|
@ -234,19 +234,18 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves an HTTP request cookie, or null if it is not present.
|
* Retrieves an HTTP request cookie, or a default value if it is not present.
|
||||||
*
|
*
|
||||||
* @todo UPDATE FOR THE NEW SYNTAX THINGY WITH THE LIST<STRING>!!!!!!!!!!!
|
|
||||||
* @param string $name Name of the request cookie.
|
* @param string $name Name of the request cookie.
|
||||||
* @param int $filter A PHP filter extension filter constant.
|
* @param int $filter A PHP filter extension filter constant.
|
||||||
* @param array<string, mixed>|int $options Options for the PHP filter.
|
* @param array<string, mixed>|int $options Options for the PHP filter.
|
||||||
* @return mixed Value of the cookie, null if not present.
|
* @param mixed $default Default value.
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getCookie(string $name, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed {
|
public function getCookie(string $name, int $filter = FILTER_DEFAULT, array|int $options = 0, mixed $default = null): mixed {
|
||||||
if(!isset($this->cookies[$name]))
|
return isset($this->cookies[$name])
|
||||||
return null;
|
? (filter_var($this->cookies[$name], $filter, $options) ?? $default)
|
||||||
|
: $default;
|
||||||
return filter_var($this->cookies[$name], $filter, $options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -263,16 +262,6 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
return $this->with(params: $query);
|
return $this->with(params: $query);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a query field is present.
|
|
||||||
*
|
|
||||||
* @param string $name Name of the query field.
|
|
||||||
* @return bool true if the field is present, false if not.
|
|
||||||
*/
|
|
||||||
public function hasParam(string $name): bool {
|
|
||||||
return isset($this->params[$name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all HTTP request query fields as a query string.
|
* Retrieves all HTTP request query fields as a query string.
|
||||||
*
|
*
|
||||||
|
@ -285,24 +274,68 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
: http_build_query($this->params, '', '&', $spacesAsPlus ? PHP_QUERY_RFC1738 : PHP_QUERY_RFC3986);
|
: http_build_query($this->params, '', '&', $spacesAsPlus ? PHP_QUERY_RFC1738 : PHP_QUERY_RFC3986);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a query field is present.
|
||||||
|
*
|
||||||
|
* @param string $name Name of the query field.
|
||||||
|
* @return bool true if the field is present, false if not.
|
||||||
|
*/
|
||||||
|
public function hasParam(string $name): bool {
|
||||||
|
return isset($this->params[$name]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves an HTTP request query field, or null if it is not present.
|
* Retrieves an HTTP request query field, or null if it is not present.
|
||||||
*
|
*
|
||||||
* @todo UPDATE FOR THE NEW SYNTAX THINGY WITH THE LIST<?STRING>!!!!!!!!!!!
|
|
||||||
* @param string $name Name of the request query field.
|
* @param string $name Name of the request query field.
|
||||||
* @param int $filter A PHP filter extension filter constant.
|
* @param int $filter A PHP filter extension filter constant.
|
||||||
* @param mixed[]|int $options Options for the PHP filter.
|
* @param mixed[]|int $options Options for the PHP filter.
|
||||||
* @param ?scalar $default Default value to fall back on.
|
* @param mixed $default Default value to fall back on.
|
||||||
* @return ?scalar Value of the query field, null if not present.
|
* @return mixed Value of the query field, null if not present.
|
||||||
*/
|
*/
|
||||||
public function getParam(string $name, int $filter = FILTER_DEFAULT, array|int $options = 0, mixed $default = null): mixed {
|
public function getParam(
|
||||||
if(!isset($this->params[$name]))
|
string $name,
|
||||||
|
int $filter = FILTER_DEFAULT,
|
||||||
|
array|int $options = 0,
|
||||||
|
mixed $default = null,
|
||||||
|
): mixed {
|
||||||
|
return $this->getParamAt($name, 0, $filter, $options, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves an HTTP request query field, or null if it is not present.
|
||||||
|
*
|
||||||
|
* @param string $name Name of the request query field.
|
||||||
|
* @param int $index Index of the parameter value.
|
||||||
|
* @param int $filter A PHP filter extension filter constant.
|
||||||
|
* @param mixed[]|int $options Options for the PHP filter.
|
||||||
|
* @param mixed $default Default value to fall back on.
|
||||||
|
* @return mixed Value of the query field, null if not present.
|
||||||
|
*/
|
||||||
|
public function getParamAt(
|
||||||
|
string $name,
|
||||||
|
int $index,
|
||||||
|
int $filter = FILTER_DEFAULT,
|
||||||
|
array|int $options = 0,
|
||||||
|
mixed $default = null,
|
||||||
|
): mixed {
|
||||||
|
if(!isset($this->params[$name]) && isset($this->params[$name][$index]))
|
||||||
return $default;
|
return $default;
|
||||||
|
|
||||||
$value = filter_var($this->params[$name], $filter, $options);
|
$value = filter_var($this->params[$name][$index], $filter, $options);
|
||||||
return is_scalar($value) ? $value : $default;
|
return is_scalar($value) ? $value : $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves how many parameters of the same name appear in the HTTP request query field.
|
||||||
|
*
|
||||||
|
* @param string $name Name of the request query field.
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getParamCount(string $name): int {
|
||||||
|
return isset($this->params[$name]) ? count($this->params[$name]) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<string, HttpUploadedFile[]> An array tree of UploadedFileInterface instances; an empty array MUST be returned if no data is present.
|
* @return array<string, HttpUploadedFile[]> An array tree of UploadedFileInterface instances; an empty array MUST be returned if no data is present.
|
||||||
*/
|
*/
|
||||||
|
@ -364,7 +397,7 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
* Parses a Cookie header string.
|
* Parses a Cookie header string.
|
||||||
*
|
*
|
||||||
* @param string $cookies Cookie header string.
|
* @param string $cookies Cookie header string.
|
||||||
* @return array<string, string[]>
|
* @return array<string, string>
|
||||||
*/
|
*/
|
||||||
public static function parseCookieString(string $cookies): array {
|
public static function parseCookieString(string $cookies): array {
|
||||||
$params = [];
|
$params = [];
|
||||||
|
@ -375,11 +408,8 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
$parts = explode('=', ltrim($paramPart, ' '), 2);
|
$parts = explode('=', ltrim($paramPart, ' '), 2);
|
||||||
if(count($parts) > 1) {
|
if(count($parts) > 1) {
|
||||||
$name = urldecode($parts[0]);
|
$name = urldecode($parts[0]);
|
||||||
$value = urldecode($parts[1]);
|
if(!array_key_exists($name, $params))
|
||||||
if(array_key_exists($name, $params))
|
$params[$name] = urldecode($parts[1]);
|
||||||
$params[$name][] = $value;
|
|
||||||
else
|
|
||||||
$params[$name] = [$value];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,20 +420,23 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
/**
|
/**
|
||||||
* Creates an HttpRequest instance from the current request.
|
* Creates an HttpRequest instance from the current request.
|
||||||
*
|
*
|
||||||
|
* @param ?array<string, mixed> $server Value of the $_SERVER variable, if null the current super-global $_SERVER is used.
|
||||||
* @return HttpRequest An instance representing the current request.
|
* @return HttpRequest An instance representing the current request.
|
||||||
*/
|
*/
|
||||||
public static function fromRequest(): HttpRequest {
|
public static function fromRequest(?array $server = null): HttpRequest {
|
||||||
|
/** @var array<string, mixed> $server */
|
||||||
|
$server ??= $_SERVER;
|
||||||
$build = new HttpRequestBuilder;
|
$build = new HttpRequestBuilder;
|
||||||
$build->remoteAddress = (string)filter_input(INPUT_SERVER, 'REMOTE_ADDR');
|
$build->remoteAddress = (string)filter_var($server['REMOTE_ADDR'] ?? '::');
|
||||||
$build->secure = filter_has_var(INPUT_SERVER, 'HTTPS');
|
$build->secure = !empty($server['HTTPS']);
|
||||||
$build->protocolVersion = (string)filter_input(INPUT_SERVER, 'SERVER_PROTOCOL');
|
$build->protocolVersion = (string)filter_var($server['SERVER_PROTOCOL'] ?? '1.1');
|
||||||
$build->method = (string)filter_input(INPUT_SERVER, 'REQUEST_METHOD');
|
$build->method = (string)filter_var($server['REQUEST_METHOD'] ?? 'GET');
|
||||||
|
|
||||||
if(filter_has_var(INPUT_SERVER, 'COUNTRY_CODE'))
|
if(!empty($server['COUNTRY_CODE']))
|
||||||
$build->countryCode = (string)filter_input(INPUT_SERVER, 'COUNTRY_CODE');
|
$build->countryCode = (string)filter_var($server['COUNTRY_CODE']);
|
||||||
|
|
||||||
// this currently doesn't "properly" support the scenario where a full url is specified in the http request
|
// this currently doesn't "properly" support the scenario where a full url is specified in the http request
|
||||||
$path = (string)filter_input(INPUT_SERVER, 'REQUEST_URI');
|
$path = (string)filter_var($server['REQUEST_URI'] ?? '/');
|
||||||
$pathQueryOffset = strpos($path, '?');
|
$pathQueryOffset = strpos($path, '?');
|
||||||
if($pathQueryOffset !== false)
|
if($pathQueryOffset !== false)
|
||||||
$path = substr($path, 0, $pathQueryOffset);
|
$path = substr($path, 0, $pathQueryOffset);
|
||||||
|
@ -417,12 +450,12 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
$path = '/' . $path;
|
$path = '/' . $path;
|
||||||
|
|
||||||
$build->path = $path;
|
$build->path = $path;
|
||||||
$build->params = HttpUri::parseQueryString((string)filter_input(INPUT_SERVER, 'QUERY_STRING'));
|
$build->params = HttpUri::parseQueryString((string)filter_var($server['QUERY_STRING'] ?? ''));
|
||||||
|
|
||||||
$contentType = null;
|
$contentType = null;
|
||||||
$contentLength = 0;
|
$contentLength = 0;
|
||||||
|
|
||||||
$headers = self::getRawRequestHeaders();
|
$headers = self::getRawRequestHeaders($server);
|
||||||
foreach($headers as $name => $value) {
|
foreach($headers as $name => $value) {
|
||||||
if($name === 'content-type')
|
if($name === 'content-type')
|
||||||
try {
|
try {
|
||||||
|
@ -438,13 +471,16 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
$build->setHeader($name, $value);
|
$build->setHeader($name, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
$build->body = null;
|
$build->body = HttpStream::createStreamFromFile('php://input', 'rb');
|
||||||
|
|
||||||
return $build->toRequest();
|
return $build->toRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return array<string, string> */
|
/**
|
||||||
private static function getRawRequestHeaders(): array {
|
* @param ?array<string, mixed> $server
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
private static function getRawRequestHeaders(?array $server = null): array {
|
||||||
if(function_exists('getallheaders')) {
|
if(function_exists('getallheaders')) {
|
||||||
$raw = getallheaders();
|
$raw = getallheaders();
|
||||||
$headers = [];
|
$headers = [];
|
||||||
|
@ -455,9 +491,10 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
return $headers;
|
return $headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$server ??= $_SERVER;
|
||||||
$headers = [];
|
$headers = [];
|
||||||
|
|
||||||
foreach($_SERVER as $key => $value) {
|
foreach($server as $key => $value) {
|
||||||
if(!is_string($key) || !is_scalar($value))
|
if(!is_string($key) || !is_scalar($value))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -472,16 +509,16 @@ class HttpRequest extends HttpMessage implements ServerRequestInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isset($headers['authorization'])) {
|
if(!isset($headers['authorization'])) {
|
||||||
if(filter_has_var(INPUT_SERVER, 'REDIRECT_HTTP_AUTHORIZATION')) {
|
if(!empty($server['REDIRECT_HTTP_AUTHORIZATION'])) {
|
||||||
$headers['authorization'] = (string)filter_input(INPUT_SERVER, 'REDIRECT_HTTP_AUTHORIZATION');
|
$headers['authorization'] = (string)filter_var($server['REDIRECT_HTTP_AUTHORIZATION']);
|
||||||
} elseif(filter_has_var(INPUT_SERVER, 'PHP_AUTH_USER')) {
|
} elseif(!empty($server['PHP_AUTH_USER'])) {
|
||||||
$headers['authorization'] = sprintf('Basic %s', base64_encode(sprintf(
|
$headers['authorization'] = sprintf('Basic %s', base64_encode(sprintf(
|
||||||
'%s:%s',
|
'%s:%s',
|
||||||
(string)filter_input(INPUT_SERVER, 'PHP_AUTH_USER'),
|
(string)filter_var($server['PHP_AUTH_USER']),
|
||||||
(string)filter_input(INPUT_SERVER, 'PHP_AUTH_PW')
|
(string)filter_var($server['PHP_AUTH_PW'])
|
||||||
)));
|
)));
|
||||||
} elseif(filter_has_var(INPUT_SERVER, 'PHP_AUTH_DIGEST')) {
|
} elseif(!empty($server['PHP_AUTH_DIGEST'])) {
|
||||||
$headers['authorization'] = (string)filter_input(INPUT_SERVER, 'PHP_AUTH_DIGEST');
|
$headers['authorization'] = (string)filter_var($server['PHP_AUTH_DIGEST']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ final class HttpRequestBuilder extends HttpMessageBuilder {
|
||||||
/**
|
/**
|
||||||
* HTTP request cookies.
|
* HTTP request cookies.
|
||||||
*
|
*
|
||||||
* @var array<string, string[]>
|
* @var array<string, string>
|
||||||
*/
|
*/
|
||||||
public array $cookies = [];
|
public array $cookies = [];
|
||||||
|
|
||||||
|
@ -104,30 +104,7 @@ final class HttpRequestBuilder extends HttpMessageBuilder {
|
||||||
* @param string $value Value of the cookie.
|
* @param string $value Value of the cookie.
|
||||||
*/
|
*/
|
||||||
public function setCookie(string $name, string $value): void {
|
public function setCookie(string $name, string $value): void {
|
||||||
$this->cookies[$name] = [$value];
|
$this->cookies[$name] = $value;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a value for a HTTP request cookie.
|
|
||||||
*
|
|
||||||
* @param string $name Name of the cookie.
|
|
||||||
* @param string $value Value of the cookie.
|
|
||||||
*/
|
|
||||||
public function addCookie(string $name, string $value): void {
|
|
||||||
if(array_key_exists($name, $this->cookies))
|
|
||||||
$this->cookies[$name][] = $value;
|
|
||||||
else
|
|
||||||
$this->cookies[$name] = [$value];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets values for a HTTP request cookie.
|
|
||||||
*
|
|
||||||
* @param string $name Name of the cookie.
|
|
||||||
* @param string[] $values Values of the cookie.
|
|
||||||
*/
|
|
||||||
public function setCookieValues(string $name, array $values): void {
|
|
||||||
$this->cookies[$name] = $values;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,12 +5,13 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use Index\Http\HttpUri;
|
use Index\Http\{HttpRequest,HttpUri};
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use PHPUnit\Framework\Attributes\{CoversClass,DataProvider};
|
use PHPUnit\Framework\Attributes\{CoversClass,DataProvider};
|
||||||
use Psr\Http\Message\UriInterface;
|
use Psr\Http\Message\UriInterface;
|
||||||
|
|
||||||
// based on https://github.com/bakame-php/psr7-uri-interface-tests/blob/5a556fdfe668a6c6a14772efeba6134c0b7dae34/tests/AbstractUriTestCase.php
|
// based on https://github.com/bakame-php/psr7-uri-interface-tests/blob/5a556fdfe668a6c6a14772efeba6134c0b7dae34/tests/AbstractUriTestCase.php
|
||||||
|
#[CoversClass(HttpRequest::class)]
|
||||||
#[CoversClass(HttpUri::class)]
|
#[CoversClass(HttpUri::class)]
|
||||||
final class HttpUriTest extends TestCase {
|
final class HttpUriTest extends TestCase {
|
||||||
private const string URI = 'http://username:pwd@secure.example.com:443/meow/soap.php?soup=beans#mewow';
|
private const string URI = 'http://username:pwd@secure.example.com:443/meow/soap.php?soup=beans#mewow';
|
||||||
|
@ -502,4 +503,36 @@ final class HttpUriTest extends TestCase {
|
||||||
public function testBuildQueryString(array $queryParams, string $expected): void {
|
public function testBuildQueryString(array $queryParams, string $expected): void {
|
||||||
$this->assertEquals(HttpUri::buildQueryString($queryParams), $expected);
|
$this->assertEquals(HttpUri::buildQueryString($queryParams), $expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return array<array{0: string, 1: array<string, string>}> */
|
||||||
|
public static function cookieStringProvider(): array {
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'',
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'soup=meow',
|
||||||
|
['soup' => 'meow']
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'soup=meow;the=the1; the2=the3; the4=the5;',
|
||||||
|
['soup' => 'meow', 'the' => 'the1', 'the2' => 'the3', 'the4' => 'the5']
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'test%5B%5D=%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82',
|
||||||
|
['test[]' => 'あああああああ']
|
||||||
|
],
|
||||||
|
[
|
||||||
|
' =empty',
|
||||||
|
['' => 'empty']
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param array<string, string> $expected */
|
||||||
|
#[DataProvider('cookieStringProvider')]
|
||||||
|
public function testParseCookieString(string $cookieString, array $expected): void {
|
||||||
|
$this->assertEquals(HttpRequest::parseCookieString($cookieString), $expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue