From 9e11a1fafaa1b48167cf5b4e6bcd0716f1c83ade Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Tue, 14 Jul 2026 16:09:11 +0200 Subject: [PATCH 1/4] refactor: Use more strict rector rules Signed-off-by: Carl Schwan --- .php-cs-fixer.dist.php | 1 + lib/functions.php | 4 ++-- rector.php | 27 +++++++++++++++++++++------ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 4d464eb3..cbf2d10d 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -6,6 +6,7 @@ ->in(__DIR__) ->append([ __FILE__, + 'rector.php', ]); $config->setRules([ '@PSR1' => true, diff --git a/lib/functions.php b/lib/functions.php index a4bb5444..0d13b39e 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -374,7 +374,7 @@ function parseMimeType(string $str): array */ function encodePath(string $path): string { - return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\)\/:@])/', fn ($match) => '%'.sprintf('%02x', ord($match[0])), $path); + return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\)\/:@])/', fn ($match): string => '%'.sprintf('%02x', ord($match[0])), $path); } /** @@ -384,7 +384,7 @@ function encodePath(string $path): string */ function encodePathSegment(string $pathSegment): string { - return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\):@])/', fn ($match) => '%'.sprintf('%02x', ord($match[0])), $pathSegment); + return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\):@])/', fn ($match): string => '%'.sprintf('%02x', ord($match[0])), $pathSegment); } /** diff --git a/rector.php b/rector.php index 51448c0a..49f2bc1b 100644 --- a/rector.php +++ b/rector.php @@ -2,9 +2,10 @@ declare(strict_types=1); +use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector; use Rector\Config\RectorConfig; use Rector\PHPUnit\AnnotationsToAttributes\Rector\ClassMethod\DataProviderAnnotationToAttributeRector; -use Rector\TypeDeclarationDocblocks\Rector\ClassMethod\AddParamArrayDocblockFromDataProviderRector; +use Rector\PHPUnit\CodeQuality\Rector\Class_\AddSeeTestAnnotationRector; return RectorConfig::configure() ->withPaths([ @@ -12,11 +13,25 @@ __DIR__.'/lib', __DIR__.'/tests', ]) - ->withPhpSets(false, true) + ->withPhpSets(php82: true) ->withRules([ - AddParamArrayDocblockFromDataProviderRector::class, DataProviderAnnotationToAttributeRector::class, ]) - ->withTypeCoverageLevel(0) - ->withDeadCodeLevel(0) - ->withCodeQualityLevel(0); + ->withPreparedSets( + deadCode: true, + codeQuality: true, + codingStyle: true, + typeDeclarations: true, + typeDeclarationDocblocks: true, + privatization: true, + instanceOf: true, + earlyReturn: true, + rectorPreset: true, + phpunitCodeQuality: true, + doctrineCodeQuality: true, + symfonyCodeQuality: true, + symfonyConfigs: true, + )->withSkip([ + AddSeeTestAnnotationRector::class, + EncapsedStringsToSprintfRector::class, + ]); From bd013b9516a80b91fbe3cb50da014fe21b076cd6 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Tue, 14 Jul 2026 16:11:36 +0200 Subject: [PATCH 2/4] chore: Run composer rector Signed-off-by: Carl Schwan --- examples/asyncclient.php | 10 +- examples/basicauth.php | 2 + examples/client.php | 2 + examples/digestauth.php | 2 + examples/reverseproxy.php | 2 + lib/Auth/AWS.php | 10 +- lib/Auth/Digest.php | 10 +- lib/Client.php | 34 +++-- lib/Message.php | 5 + lib/Request.php | 9 +- lib/Response.php | 9 +- lib/Sapi.php | 8 ++ lib/functions.php | 23 ++- tests/HTTP/Auth/AWSTest.php | 54 +++---- tests/HTTP/Auth/BasicTest.php | 14 +- tests/HTTP/Auth/BearerTest.php | 15 +- tests/HTTP/Auth/DigestTest.php | 22 +-- tests/HTTP/ClientTest.php | 159 ++++++++++----------- tests/HTTP/FunctionsTest.php | 201 ++++++++++++-------------- tests/HTTP/MessageDecoratorTest.php | 67 ++++----- tests/HTTP/MessageTest.php | 97 +++++-------- tests/HTTP/NegotiateTest.php | 203 +++++++++++++-------------- tests/HTTP/RequestDecoratorTest.php | 47 ++++--- tests/HTTP/RequestTest.php | 34 ++--- tests/HTTP/ResponseDecoratorTest.php | 19 +-- tests/HTTP/ResponseTest.php | 20 +-- tests/HTTP/SapiTest.php | 114 ++++++++------- tests/HTTP/URLUtilTest.php | 56 ++++---- tests/www/connection_aborted.php | 2 +- tests/www/large.php | 2 + 30 files changed, 610 insertions(+), 642 deletions(-) diff --git a/examples/asyncclient.php b/examples/asyncclient.php index 30892688..a38d94ee 100644 --- a/examples/asyncclient.php +++ b/examples/asyncclient.php @@ -32,26 +32,26 @@ $client = new Client(); for ($i = 0; $i < 1000; ++$i) { - echo "$i sending\n"; + echo "{$i} sending\n"; $client->sendAsync( $request, // This is the 'success' callback function ($response) use ($i): void { - echo "$i -> ".$response->getStatus()."\n"; + echo "{$i} -> ".$response->getStatus()."\n"; }, // This is the 'error' callback. It is called for general connection // problems (such as not being able to connect to a host, dns errors, // etc.) and also cases where a response was returned, but it had a // status code of 400 or higher. - function ($error) use ($i): void { + function (array $error) use ($i): void { if (Client::STATUS_CURLERROR === $error['status']) { // Curl errors - echo "$i -> curl error: ".$error['curl_errmsg']."\n"; + echo "{$i} -> curl error: ".$error['curl_errmsg']."\n"; } else { // HTTP errors - echo "$i -> ".$error['response']->getStatus()."\n"; + echo "{$i} -> ".$error['response']->getStatus()."\n"; } } ); diff --git a/examples/basicauth.php b/examples/basicauth.php index 9c13da84..b4e727b3 100644 --- a/examples/basicauth.php +++ b/examples/basicauth.php @@ -1,5 +1,7 @@ $blocksize) { $key = pack('H*', sha1($key)); } + $key = str_pad($key, $blocksize, chr(0x00)); $ipad = str_repeat(chr(0x36), $blocksize); $opad = str_repeat(chr(0x5C), $blocksize); - $hmac = pack('H*', sha1(($key ^ $opad).pack('H*', sha1(($key ^ $ipad).$message)))); - return $hmac; + return pack('H*', sha1(($key ^ $opad).pack('H*', sha1(($key ^ $ipad).$message)))); } } diff --git a/lib/Auth/Digest.php b/lib/Auth/Digest.php index e54fad06..58312dc0 100644 --- a/lib/Auth/Digest.php +++ b/lib/Auth/Digest.php @@ -35,15 +35,20 @@ class Digest extends AbstractAuth * These constants are used in setQOP();. */ public const QOP_AUTH = 1; + public const QOP_AUTHINT = 2; protected string $nonce; + protected string $opaque; + /** * @var array|bool */ protected $digestParts; + protected string $A1; + protected int $qop = self::QOP_AUTH; /** @@ -133,6 +138,7 @@ protected function validate(): bool if (0 === ($this->qop & self::QOP_AUTHINT)) { return false; } + // We need to add an MD5 of the entire request body to the A2 part of the hash $body = $this->request->getBody(); $this->request->setBody($body); @@ -191,7 +197,7 @@ public function getDigest(): ?string * * @return false|array */ - protected function parseDigest(string $digest) + protected function parseDigest(string $digest): array|false { // protect against missing data $needed_parts = ['nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1]; @@ -204,6 +210,6 @@ protected function parseDigest(string $digest) unset($needed_parts[$m[1]]); } - return (count($needed_parts) > 0) ? false : $data; + return ([] !== $needed_parts) ? false : $data; } } diff --git a/lib/Client.php b/lib/Client.php index 40d2cc9f..17c0473e 100644 --- a/lib/Client.php +++ b/lib/Client.php @@ -149,9 +149,7 @@ public function send(RequestInterface $request): ResponseInterface // If retry was still set to false, it means no event handler // dealt with the problem. In this case we just re-throw the // exception. - if (!$retry) { - throw $e; - } + throw $e; } if ($retry) { @@ -194,7 +192,7 @@ public function sendAsync(RequestInterface $request, ?callable $success = null, public function poll(): bool { // nothing to do? - if (0 === count($this->curlMultiMap)) { + if ([] === $this->curlMultiMap) { return false; } @@ -264,7 +262,7 @@ public function poll(): bool } } while ($messagesInQueue > 0); - return count($this->curlMultiMap) > 0; + return [] !== $this->curlMultiMap; } /** @@ -335,7 +333,7 @@ protected function doRequest(RequestInterface $request): ResponseInterface * * @var resource|null */ - private $curlHandle; + private \CurlHandle|bool|null $curlHandle = null; /** * Handler for curl_multi requests. @@ -344,7 +342,7 @@ protected function doRequest(RequestInterface $request): ResponseInterface * * @var resource|null */ - private $curlMultiHandle; + private ?\CurlMultiHandle $curlMultiHandle = null; /** * Has a list of curl handles, as well as their associated success and @@ -391,6 +389,7 @@ protected function createCurlSettingsArray(RequestInterface $request): array // post local files. $settings[CURLOPT_POSTFIELDS] = (string) $body; } + $settings[CURLOPT_CUSTOMREQUEST] = $request->getMethod(); break; } @@ -405,6 +404,7 @@ protected function createCurlSettingsArray(RequestInterface $request): array if ([] !== $nHeaders) { $settings[CURLOPT_HTTPHEADER] = $nHeaders; } + $settings[CURLOPT_URL] = $request->getUrl(); // Prefer string-based protocol constants (PHP 8.3+), fall back to // bitmask constants for older PHP versions. When PHP eventually @@ -422,7 +422,9 @@ protected function createCurlSettingsArray(RequestInterface $request): array } public const STATUS_SUCCESS = 0; + public const STATUS_CURLERROR = 1; + public const STATUS_HTTPERROR = 2; /** @@ -437,17 +439,12 @@ private function parseResponse(string $response, $curlHandle): array if ($separatedHeaders) { $resourceId = (int) $curlHandle; - if (isset($this->headerLinesMap[$resourceId])) { - $headers = $this->headerLinesMap[$resourceId]; - } else { - $headers = []; - } - $response = $this->parseCurlResponse($headers, $response, $curlHandle); - } else { - $response = $this->parseCurlResult($response, $curlHandle); + $headers = $this->headerLinesMap[$resourceId] ?? []; + + return $this->parseCurlResponse($headers, $response, $curlHandle); } - return $response; + return $this->parseCurlResult($response, $curlHandle); } /** @@ -576,9 +573,10 @@ protected function parseCurlResult(string $response, $curlHandle): array */ protected function sendAsyncInternal(RequestInterface $request, callable $success, callable $error, int $retryCount = 0): void { - if (null === $this->curlMultiHandle) { + if (!$this->curlMultiHandle instanceof \CurlMultiHandle) { $this->curlMultiHandle = curl_multi_init(); } + $curl = curl_init(); curl_setopt_array( $curl, @@ -611,7 +609,7 @@ protected function curlExec($curlHandle): string $result = curl_exec($curlHandle); if (false === $result) { - $result = ''; + return ''; } return $result; diff --git a/lib/Message.php b/lib/Message.php index 9f360866..2fdbecf4 100644 --- a/lib/Message.php +++ b/lib/Message.php @@ -50,6 +50,7 @@ public function getBodyAsStream() if (is_callable($this->body)) { $body = $this->getBodyAsString(); } + if (is_string($body) || null === $body) { $stream = fopen('php://temp', 'r+'); fwrite($stream, (string) $body); @@ -73,15 +74,18 @@ public function getBodyAsString(): string if (is_string($body)) { return $body; } + if (null === $body) { return ''; } + if (is_callable($body)) { ob_start(); $body(); return ob_get_clean(); } + $contentLength = $this->getHeader('Content-Length'); if (null !== $contentLength && ctype_digit($contentLength)) { return stream_get_contents($body, (int) $contentLength); @@ -265,6 +269,7 @@ public function removeHeader(string $name): bool if (!isset($this->headers[$name])) { return false; } + unset($this->headers[$name]); return true; diff --git a/lib/Request.php b/lib/Request.php index 33783059..d969968f 100644 --- a/lib/Request.php +++ b/lib/Request.php @@ -118,7 +118,7 @@ public function getAbsoluteUrl(): string ?? parse_url($url, PHP_URL_HOST) ?? 'localhost'; // Guessing we're a http endpoint. - $this->absoluteUrl = "http://$host$url"; + $this->absoluteUrl = "http://{$host}{$url}"; } } @@ -169,6 +169,7 @@ public function getPath(): string $uri = str_replace('//', '/', $this->getUrl()); $uri = Uri\normalize($uri); + $baseUri = Uri\normalize($this->getBaseUrl()); if (str_starts_with($uri, $baseUri)) { @@ -181,6 +182,7 @@ public function getPath(): string if ($uri.'/' === $baseUri) { return ''; } + // A special case, if the baseUri was accessed without a trailing // slash, we'll accept it as well. @@ -263,12 +265,13 @@ public function __toString(): string [$v] = explode(' ', (string) $v, 2); $v .= ' REDACTED'; } + $out .= $key.': '.$v."\r\n"; } } + $out .= "\r\n"; - $out .= $this->getBodyAsString(); - return $out; + return $out.$this->getBodyAsString(); } } diff --git a/lib/Response.php b/lib/Response.php index 648d8e9c..6ba5d975 100644 --- a/lib/Response.php +++ b/lib/Response.php @@ -58,7 +58,7 @@ class Response extends Message implements ResponseInterface 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', - 418 => 'I\'m a teapot', // RFC 2324 + 418 => "I'm a teapot", // RFC 2324 421 => 'Misdirected Request', // RFC7540 (HTTP/2) 422 => 'Unprocessable Entity', // RFC 4918 423 => 'Locked', // RFC 4918 @@ -106,9 +106,11 @@ public function __construct($status = 500, ?array $headers = null, $body = null) if (null !== $status) { $this->setStatus($status); } + if (null !== $headers) { $this->setHeaders($headers); } + if (null !== $body) { $this->setBody($body); } @@ -156,6 +158,7 @@ public function setStatus($status): void $statusText, ) = explode(' ', $status, 2); } + $statusCode = (int) $statusCode; if ($statusCode < 100 || $statusCode > 999) { throw new \InvalidArgumentException('The HTTP status code must be exactly 3 digits'); @@ -178,9 +181,9 @@ public function __toString(): string $str .= $key.': '.$v."\r\n"; } } + $str .= "\r\n"; - $str .= $this->getBodyAsString(); - return $str; + return $str.$this->getBodyAsString(); } } diff --git a/lib/Sapi.php b/lib/Sapi.php index 64a29f57..2ad87ea8 100644 --- a/lib/Sapi.php +++ b/lib/Sapi.php @@ -104,6 +104,7 @@ public static function sendResponse(ResponseInterface $response): void $left -= stream_copy_to_stream($body, $output, min($delta, $left)); } } + while ($left > 0) { $copied = stream_copy_to_stream($body, $output, min($left, $chunk_size)); // stream_copy_to_stream($src, $dest, $maxLength) must return the number of bytes copied or false in case of failure @@ -113,12 +114,14 @@ public static function sendResponse(ResponseInterface $response): void if ($copied <= 0) { break; } + // Abort on client disconnect. // With ignore_user_abort(true), the script is not aborted on client disconnect. // To avoid reading the entire stream and dismissing the data afterward, check between the chunks if the client is still there. if (1 === ignore_user_abort() && 1 === connection_aborted()) { break; } + $left -= $copied; } } else { @@ -160,6 +163,7 @@ public static function createFromServerArray(array $serverArray): Request } elseif ('HTTP/2.0' === $value) { $httpVersion = '2.0'; } + break; case 'REQUEST_METHOD': $method = $value; @@ -182,6 +186,7 @@ public static function createFromServerArray(array $serverArray): Request if (isset($serverArray['PHP_AUTH_PW'])) { $headers['Authorization'] = 'Basic '.base64_encode($value.':'.$serverArray['PHP_AUTH_PW']); } + break; // Similarly, mod_php may also screw around with digest auth. @@ -204,6 +209,7 @@ public static function createFromServerArray(array $serverArray): Request if ('' !== $value && 'off' !== $value) { $protocol = 'https'; } + break; default: @@ -221,6 +227,7 @@ public static function createFromServerArray(array $serverArray): Request $header = str_replace(' ', '-', $header); $headers[$header] = $value; } + break; } } @@ -232,6 +239,7 @@ public static function createFromServerArray(array $serverArray): Request if (null === $method) { throw new \InvalidArgumentException('The _SERVER array must have a REQUEST_METHOD key'); } + $r = new Request($method, $url, $headers); $r->setHttpVersion($httpVersion); $r->setRawServerData($serverArray); diff --git a/lib/functions.php b/lib/functions.php index 0d13b39e..f2db2307 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -14,7 +14,6 @@ * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ - /** * Parses an HTTP date-string. * @@ -27,10 +26,8 @@ * * See: * http://tools.ietf.org/html/rfc7231#section-7.1.1.1 - * - * @return bool|\DateTime */ -function parseDate(string $dateString) +function parseDate(string $dateString): false|\DateTime { // Only the format is checked, valid ranges are checked by strtotime below $month = '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)'; @@ -50,7 +47,7 @@ function parseDate(string $dateString) // RFC 822, updated by RFC 1123 $rfc1123_date = $wkday.', '.$date1.' '.$time.' GMT'; // allowed date formats by RFC 2616 - $HTTP_date = "($rfc1123_date|$rfc850_date|$asctime_date)"; + $HTTP_date = "({$rfc1123_date}|{$rfc850_date}|{$asctime_date})"; // allow for space around the string and strip it $dateString = trim($dateString, ' '); @@ -142,6 +139,7 @@ function negotiateContentType(?string $acceptHeaderValue, array $availableOption // no match on type. continue; } + if ('*' !== $proposal['subType'] && $proposal['subType'] !== $option['subType']) { // no match on subtype. continue; @@ -153,6 +151,7 @@ function negotiateContentType(?string $acceptHeaderValue, array $availableOption if (!array_key_exists($paramName, $proposal['parameters'])) { continue 2; } + if ($paramValue !== $proposal['parameters'][$paramName]) { continue 2; } @@ -221,10 +220,10 @@ function parsePrefer($input): array $regex = << $token) # Prefer property name +(? {$token}) # Prefer property name \s* # Optional space (?: = \s* # Prefer property value - (? $word) + (? {$word}) )? (?: \s* ; (?: .*))? # Prefer parameters (ignored) $ @@ -256,11 +255,8 @@ function parsePrefer($input): array $output['handling'] = 'lenient'; break; default: - if (isset($matches['value'])) { - $value = trim($matches['value'], '"'); - } else { - $value = true; - } + $value = isset($matches['value']) ? trim($matches['value'], '"') : true; + $output[strtolower($matches['name'])] = ('' === $value) ? true : $value; break; } @@ -335,6 +331,7 @@ function parseMimeType(string $str): array // Illegal value throw new \InvalidArgumentException('Not a valid mime-type: '.$str); } + [$type, $subType] = $mimeType; foreach ($parts as $part) { @@ -403,7 +400,7 @@ function decodePathSegment(string $path): string $path = rawurldecode($path); if (!mb_check_encoding($path, 'UTF-8') && mb_check_encoding($path, 'ISO-8859-1')) { - $path = mb_convert_encoding($path, 'UTF-8', 'ISO-8859-1'); + return mb_convert_encoding($path, 'UTF-8', 'ISO-8859-1'); } return $path; diff --git a/tests/HTTP/Auth/AWSTest.php b/tests/HTTP/Auth/AWSTest.php index 35d610e8..a80fc94c 100644 --- a/tests/HTTP/Auth/AWSTest.php +++ b/tests/HTTP/Auth/AWSTest.php @@ -7,7 +7,7 @@ use Sabre\HTTP\Request; use Sabre\HTTP\Response; -class AWSTest extends \PHPUnit\Framework\TestCase +final class AWSTest extends \PHPUnit\Framework\TestCase { private Response $response; @@ -17,7 +17,7 @@ class AWSTest extends \PHPUnit\Framework\TestCase public const REALM = 'SabreDAV unittest'; - public function setUp(): void + protected function setUp(): void { $this->response = new Response(); $this->request = new Request('GET', '/'); @@ -29,8 +29,8 @@ public function testNoHeader(): void $this->request->setMethod('GET'); $result = $this->auth->init(); - self::assertFalse($result, 'No AWS Authorization header was supplied, so we should have gotten false'); - self::assertEquals(AWS::ERR_NOAWSHEADER, $this->auth->errorCode); + $this->assertFalse($result, 'No AWS Authorization header was supplied, so we should have gotten false'); + $this->assertSame(AWS::ERR_NOAWSHEADER, $this->auth->errorCode); } public function testInvalidAuthorizationHeader(): void @@ -38,7 +38,7 @@ public function testInvalidAuthorizationHeader(): void $this->request->setMethod('GET'); $this->request->setHeader('Authorization', 'Invalid Auth Header'); - self::assertFalse($this->auth->init(), 'The Invalid AWS authorization header'); + $this->assertFalse($this->auth->init(), 'The Invalid AWS authorization header'); } public function testIncorrectContentMD5(): void @@ -48,7 +48,7 @@ public function testIncorrectContentMD5(): void $this->request->setMethod('GET'); $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:sig", + 'Authorization' => "AWS {$accessKey}:sig", 'Content-MD5' => 'garbage', ]); $this->request->setUrl('/'); @@ -56,8 +56,8 @@ public function testIncorrectContentMD5(): void $this->auth->init(); $result = $this->auth->validate($secretKey); - self::assertFalse($result); - self::assertEquals(AWS::ERR_MD5CHECKSUMWRONG, $this->auth->errorCode); + $this->assertFalse($result); + $this->assertSame(AWS::ERR_MD5CHECKSUMWRONG, $this->auth->errorCode); } public function testNoDate(): void @@ -69,7 +69,7 @@ public function testNoDate(): void $this->request->setMethod('POST'); $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:sig", + 'Authorization' => "AWS {$accessKey}:sig", 'Content-MD5' => $contentMD5, ]); $this->request->setUrl('/'); @@ -78,8 +78,8 @@ public function testNoDate(): void $this->auth->init(); $result = $this->auth->validate($secretKey); - self::assertFalse($result); - self::assertEquals(AWS::ERR_INVALIDDATEFORMAT, $this->auth->errorCode); + $this->assertFalse($result); + $this->assertSame(AWS::ERR_INVALIDDATEFORMAT, $this->auth->errorCode); } public function testFutureDate(): void @@ -95,7 +95,7 @@ public function testFutureDate(): void $this->request->setMethod('POST'); $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:sig", + 'Authorization' => "AWS {$accessKey}:sig", 'Content-MD5' => $contentMD5, 'Date' => $date, ]); @@ -105,8 +105,8 @@ public function testFutureDate(): void $this->auth->init(); $result = $this->auth->validate($secretKey); - self::assertFalse($result); - self::assertEquals(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode); + $this->assertFalse($result); + $this->assertSame(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode); } public function testPastDate(): void @@ -122,7 +122,7 @@ public function testPastDate(): void $this->request->setMethod('POST'); $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:sig", + 'Authorization' => "AWS {$accessKey}:sig", 'Content-MD5' => $contentMD5, 'Date' => $date, ]); @@ -132,8 +132,8 @@ public function testPastDate(): void $this->auth->init(); $result = $this->auth->validate($secretKey); - self::assertFalse($result); - self::assertEquals(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode); + $this->assertFalse($result); + $this->assertSame(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode); } public function testIncorrectSignature(): void @@ -151,7 +151,7 @@ public function testIncorrectSignature(): void $this->request->setUrl('/'); $this->request->setMethod('POST'); $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:sig", + 'Authorization' => "AWS {$accessKey}:sig", 'Content-MD5' => $contentMD5, 'X-amz-date' => $date, ]); @@ -160,8 +160,8 @@ public function testIncorrectSignature(): void $this->auth->init(); $result = $this->auth->validate($secretKey); - self::assertFalse($result); - self::assertEquals(AWS::ERR_INVALIDSIGNATURE, $this->auth->errorCode); + $this->assertFalse($result); + $this->assertSame(AWS::ERR_INVALIDSIGNATURE, $this->auth->errorCode); } public function testValidRequest(): void @@ -176,13 +176,13 @@ public function testValidRequest(): void $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); $sig = base64_encode($this->hmacsha1($secretKey, - "POST\n$contentMD5\n\n$date\nx-amz-date:$date\n/evert" + "POST\n{$contentMD5}\n\n{$date}\nx-amz-date:{$date}\n/evert" )); $this->request->setUrl('/evert'); $this->request->setMethod('POST'); $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:$sig", + 'Authorization' => "AWS {$accessKey}:{$sig}", 'Content-MD5' => $contentMD5, 'X-amz-date' => $date, ]); @@ -192,15 +192,15 @@ public function testValidRequest(): void $this->auth->init(); $result = $this->auth->validate($secretKey); - self::assertTrue($result, 'Signature did not validate, got errorcode '.$this->auth->errorCode); - self::assertEquals($accessKey, $this->auth->getAccessKey()); + $this->assertTrue($result, 'Signature did not validate, got errorcode '.$this->auth->errorCode); + $this->assertSame($accessKey, $this->auth->getAccessKey()); } public function test401(): void { $this->auth->requireLogin(); $test = preg_match('/^AWS$/', (string) $this->response->getHeader('WWW-Authenticate'), $matches); - self::assertTrue(1 === $test, 'The WWW-Authenticate response didn\'t match our pattern'); + $this->assertSame(1, $test, "The WWW-Authenticate response didn't match our pattern"); } /** @@ -212,11 +212,11 @@ private function hmacsha1(string $key, string $message): string if (strlen($key) > $blocksize) { $key = pack('H*', sha1($key)); } + $key = str_pad($key, $blocksize, chr(0x00)); $ipad = str_repeat(chr(0x36), $blocksize); $opad = str_repeat(chr(0x5C), $blocksize); - $hmac = pack('H*', sha1(($key ^ $opad).pack('H*', sha1(($key ^ $ipad).$message)))); - return $hmac; + return pack('H*', sha1(($key ^ $opad).pack('H*', sha1(($key ^ $ipad).$message)))); } } diff --git a/tests/HTTP/Auth/BasicTest.php b/tests/HTTP/Auth/BasicTest.php index 78195281..a5c247fa 100644 --- a/tests/HTTP/Auth/BasicTest.php +++ b/tests/HTTP/Auth/BasicTest.php @@ -7,7 +7,7 @@ use Sabre\HTTP\Request; use Sabre\HTTP\Response; -class BasicTest extends \PHPUnit\Framework\TestCase +final class BasicTest extends \PHPUnit\Framework\TestCase { public function testGetCredentials(): void { @@ -17,7 +17,7 @@ public function testGetCredentials(): void $basic = new Basic('Dagger', $request, new Response()); - self::assertEquals([ + $this->assertSame([ 'user', 'pass:bla', ], $basic->getCredentials()); @@ -31,7 +31,7 @@ public function testGetInvalidCredentialsColonMissing(): void $basic = new Basic('Dagger', $request, new Response()); - self::assertNull($basic->getCredentials()); + $this->assertNull($basic->getCredentials()); } public function testGetCredentialsNoHeader(): void @@ -39,7 +39,7 @@ public function testGetCredentialsNoHeader(): void $request = new Request('GET', '/', []); $basic = new Basic('Dagger', $request, new Response()); - self::assertNull($basic->getCredentials()); + $this->assertNull($basic->getCredentials()); } public function testGetCredentialsNotBasic(): void @@ -49,7 +49,7 @@ public function testGetCredentialsNotBasic(): void ]); $basic = new Basic('Dagger', $request, new Response()); - self::assertNull($basic->getCredentials()); + $this->assertNull($basic->getCredentials()); } public function testRequireLogin(): void @@ -61,7 +61,7 @@ public function testRequireLogin(): void $basic->requireLogin(); - self::assertEquals('Basic realm="Dagger", charset="UTF-8"', $response->getHeader('WWW-Authenticate')); - self::assertEquals(401, $response->getStatus()); + $this->assertSame('Basic realm="Dagger", charset="UTF-8"', $response->getHeader('WWW-Authenticate')); + $this->assertSame(401, $response->getStatus()); } } diff --git a/tests/HTTP/Auth/BearerTest.php b/tests/HTTP/Auth/BearerTest.php index 22df027c..0090c511 100644 --- a/tests/HTTP/Auth/BearerTest.php +++ b/tests/HTTP/Auth/BearerTest.php @@ -7,7 +7,7 @@ use Sabre\HTTP\Request; use Sabre\HTTP\Response; -class BearerTest extends \PHPUnit\Framework\TestCase +final class BearerTest extends \PHPUnit\Framework\TestCase { public function testGetToken(): void { @@ -17,10 +17,7 @@ public function testGetToken(): void $bearer = new Bearer('Dagger', $request, new Response()); - self::assertEquals( - '12345', - $bearer->getToken() - ); + $this->assertEquals('12345', $bearer->getToken()); } public function testGetCredentialsNoHeader(): void @@ -28,7 +25,7 @@ public function testGetCredentialsNoHeader(): void $request = new Request('GET', '/', []); $bearer = new Bearer('Dagger', $request, new Response()); - self::assertNull($bearer->getToken()); + $this->assertNull($bearer->getToken()); } public function testGetCredentialsNotBearer(): void @@ -38,7 +35,7 @@ public function testGetCredentialsNotBearer(): void ]); $bearer = new Bearer('Dagger', $request, new Response()); - self::assertNull($bearer->getToken()); + $this->assertNull($bearer->getToken()); } public function testRequireLogin(): void @@ -49,7 +46,7 @@ public function testRequireLogin(): void $bearer->requireLogin(); - self::assertEquals('Bearer realm="Dagger"', $response->getHeader('WWW-Authenticate')); - self::assertEquals(401, $response->getStatus()); + $this->assertSame('Bearer realm="Dagger"', $response->getHeader('WWW-Authenticate')); + $this->assertSame(401, $response->getStatus()); } } diff --git a/tests/HTTP/Auth/DigestTest.php b/tests/HTTP/Auth/DigestTest.php index 5391695a..d15363bf 100644 --- a/tests/HTTP/Auth/DigestTest.php +++ b/tests/HTTP/Auth/DigestTest.php @@ -7,7 +7,7 @@ use Sabre\HTTP\Request; use Sabre\HTTP\Response; -class DigestTest extends \PHPUnit\Framework\TestCase +final class DigestTest extends \PHPUnit\Framework\TestCase { private Response $response; @@ -20,7 +20,7 @@ class DigestTest extends \PHPUnit\Framework\TestCase public const REALM = 'SabreDAV unittest'; - public function setUp(): void + protected function setUp(): void { $this->response = new Response(); $this->request = new Request('GET', '/'); @@ -50,10 +50,10 @@ public function testDigest(): void $this->auth->init(); - self::assertEquals($username, $this->auth->getUsername()); - self::assertEquals(self::REALM, $this->auth->getRealm()); - self::assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1'); - self::assertTrue($this->auth->validatePassword($password), 'Authentication is deemed invalid through validatePassword'); + $this->assertSame($username, $this->auth->getUsername()); + $this->assertSame(self::REALM, $this->auth->getRealm()); + $this->assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1'); + $this->assertTrue($this->auth->validatePassword($password), 'Authentication is deemed invalid through validatePassword'); } public function testInvalidDigest(): void @@ -79,7 +79,7 @@ public function testInvalidDigest(): void $this->auth->init(); - self::assertFalse($this->auth->validateA1(md5($username.':'.self::REALM.':'.($password.'randomness'))), 'Authentication is deemed invalid through validateA1'); + $this->assertFalse($this->auth->validateA1(md5($username.':'.self::REALM.':'.($password.'randomness'))), 'Authentication is deemed invalid through validateA1'); } public function testInvalidDigest2(): void @@ -88,7 +88,7 @@ public function testInvalidDigest2(): void $this->request->setHeader('Authorization', 'basic blablabla'); $this->auth->init(); - self::assertFalse($this->auth->validateA1(md5('user:realm:password'))); + $this->assertFalse($this->auth->validateA1(md5('user:realm:password'))); } public function testDigestAuthInt(): void @@ -116,7 +116,7 @@ public function testDigestAuthInt(): void $this->auth->init(); - self::assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1'); + $this->assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1'); } public function testDigestAuthBoth(): void @@ -144,7 +144,7 @@ public function testDigestAuthBoth(): void $this->auth->init(); - self::assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1'); + $this->assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1'); } /** @@ -163,7 +163,7 @@ private function getServerTokens(int $qop = Digest::QOP_AUTH): array $test = preg_match('/Digest realm="'.self::REALM.'",qop="'.$qopstr.'",nonce="([0-9a-f]*)",opaque="([0-9a-f]*)"/', (string) $this->response->getHeader('WWW-Authenticate'), $matches); - self::assertTrue(1 === $test, 'The WWW-Authenticate response didn\'t match our pattern. We received: '.$this->response->getHeader('WWW-Authenticate')); + $this->assertSame(1, $test, "The WWW-Authenticate response didn't match our pattern. We received: ".$this->response->getHeader('WWW-Authenticate')); $nonce = $matches[1]; $opaque = $matches[2]; diff --git a/tests/HTTP/ClientTest.php b/tests/HTTP/ClientTest.php index 817cb4c7..2949c3ba 100644 --- a/tests/HTTP/ClientTest.php +++ b/tests/HTTP/ClientTest.php @@ -4,14 +4,14 @@ namespace Sabre\HTTP; -class ClientTest extends \PHPUnit\Framework\TestCase +final class ClientTest extends \PHPUnit\Framework\TestCase { /** * Returns the expected curl protocol settings depending on available constants. * * @return array */ - private static function protocolSettings(): array + private function protocolSettings(): array { if (defined('CURLOPT_PROTOCOLS_STR') && defined('CURLOPT_REDIR_PROTOCOLS_STR')) { return [ @@ -46,9 +46,9 @@ public function testCreateCurlSettingsArrayGET(): void CURLOPT_URL => 'http://example.org/', CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ] + self::protocolSettings(); + ] + $this->protocolSettings(); - self::assertEquals($settings, $client->createCurlSettingsArray($request)); + $this->assertEquals($settings, $client->createCurlSettingsArray($request)); } public function testCreateCurlSettingsHTTPHeader(): void @@ -71,9 +71,9 @@ public function testCreateCurlSettingsHTTPHeader(): void CURLOPT_URL => 'http://example.org/', CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ] + self::protocolSettings(); + ] + $this->protocolSettings(); - self::assertEquals($settings, $client->createCurlSettingsArray($request)); + $this->assertEquals($settings, $client->createCurlSettingsArray($request)); } public function testCreateCurlSettingsArrayHEAD(): void @@ -89,9 +89,9 @@ public function testCreateCurlSettingsArrayHEAD(): void CURLOPT_HTTPHEADER => ['X-Foo: bar'], CURLOPT_URL => 'http://example.org/', CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ] + self::protocolSettings(); + ] + $this->protocolSettings(); - self::assertEquals($settings, $client->createCurlSettingsArray($request)); + $this->assertEquals($settings, $client->createCurlSettingsArray($request)); } public function testCreateCurlSettingsArrayGETAfterHEAD(): void @@ -115,9 +115,9 @@ public function testCreateCurlSettingsArrayGETAfterHEAD(): void CURLOPT_NOBODY => false, CURLOPT_URL => 'http://example.org/', CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ] + self::protocolSettings(); + ] + $this->protocolSettings(); - self::assertEquals($settings, $client->createCurlSettingsArray($request)); + $this->assertEquals($settings, $client->createCurlSettingsArray($request)); } public function testCreateCurlSettingsArrayPUTStream(): void @@ -140,9 +140,9 @@ public function testCreateCurlSettingsArrayPUTStream(): void CURLOPT_HTTPHEADER => ['X-Foo: bar'], CURLOPT_URL => 'http://example.org/', CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ] + self::protocolSettings(); + ] + $this->protocolSettings(); - self::assertEquals($settings, $client->createCurlSettingsArray($request)); + $this->assertEquals($settings, $client->createCurlSettingsArray($request)); } public function testCreateCurlSettingsArrayPUTString(): void @@ -159,9 +159,9 @@ public function testCreateCurlSettingsArrayPUTString(): void CURLOPT_HTTPHEADER => ['X-Foo: bar'], CURLOPT_URL => 'http://example.org/', CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ] + self::protocolSettings(); + ] + $this->protocolSettings(); - self::assertEquals($settings, $client->createCurlSettingsArray($request)); + $this->assertEquals($settings, $client->createCurlSettingsArray($request)); } public function testIssue89MultiplePutInfileGivesWarning(): void @@ -171,20 +171,20 @@ public function testIssue89MultiplePutInfileGivesWarning(): void $request = new Request('POST', 'http://example.org/', ['X-Foo' => 'bar'], 'body'); $settings = $client->createCurlSettingsArray($request); - self::assertArrayNotHasKey(CURLOPT_PUT, $settings); - self::assertArrayNotHasKey(CURLOPT_INFILE, $settings); + $this->assertArrayNotHasKey(CURLOPT_PUT, $settings); + $this->assertArrayNotHasKey(CURLOPT_INFILE, $settings); $request = new Request('POST', 'http://example.org/', ['X-Foo' => 'bar'], $tmpFile); $settings = $client->createCurlSettingsArray($request); - self::assertEquals(true, $settings[CURLOPT_PUT]); - self::assertEquals($tmpFile, $settings[CURLOPT_INFILE]); + $this->assertEquals(true, $settings[CURLOPT_PUT]); + $this->assertEquals($tmpFile, $settings[CURLOPT_INFILE]); $request = new Request('POST', 'http://example.org/', ['X-Foo' => 'bar'], 'body'); $settings = $client->createCurlSettingsArray($request); - self::assertArrayNotHasKey(CURLOPT_PUT, $settings); - self::assertArrayNotHasKey(CURLOPT_INFILE, $settings); + $this->assertArrayNotHasKey(CURLOPT_PUT, $settings); + $this->assertArrayNotHasKey(CURLOPT_INFILE, $settings); } public function testSend(): void @@ -198,19 +198,16 @@ public function testSend(): void $response = $client->send($request); - self::assertEquals(200, $response->getStatus()); + $this->assertSame(200, $response->getStatus()); } - /** - * @return false|string - */ - protected function getAbsoluteUrl(string $path) + protected function getAbsoluteUrl(string $path): string|false { $baseUrl = getenv('BASEURL'); if ($baseUrl) { $path = ltrim($path, '/'); - return "$baseUrl/$path"; + return "{$baseUrl}/{$path}"; } return false; @@ -238,12 +235,8 @@ public function testSendToGetLargeContent(): void $client = new Client(); $response = $client->send($request); - self::assertEquals(200, $response->getStatus()); - self::assertLessThan( - (int) $maxPeakMemoryUsage, - memory_get_peak_usage(), - "Hint: you can adjust the max peak memory usage allowed for this test by defining env variable $maxPeakMemoryUsageEnvVariable to be the desired max bytes" - ); + $this->assertSame(200, $response->getStatus()); + $this->assertLessThan((int) $maxPeakMemoryUsage, memory_get_peak_usage(), "Hint: you can adjust the max peak memory usage allowed for this test by defining env variable {$maxPeakMemoryUsageEnvVariable} to be the desired max bytes"); } /** @@ -260,12 +253,12 @@ public function testSendAsync(): void $request = new Request('GET', $url); $client->sendAsync($request, function (ResponseInterface $response): void { - self::assertEquals("foo\n", $response->getBody()); - self::assertEquals(200, $response->getStatus()); - self::assertEquals(4, $response->getHeader('Content-Length')); - }, function ($error) use ($request): void { + $this->assertEquals("foo\n", $response->getBody()); + $this->assertSame(200, $response->getStatus()); + $this->assertEquals(4, $response->getHeader('Content-Length')); + }, function ($error) use ($request): never { $url = $request->getUrl(); - self::fail("Failed to GET $url"); + self::fail("Failed to GET {$url}"); }); $client->wait(); @@ -285,23 +278,23 @@ public function testSendAsynConsecutively(): void $request = new Request('GET', $url); $client->sendAsync($request, function (ResponseInterface $response): void { - self::assertEquals("foo\n", $response->getBody()); - self::assertEquals(200, $response->getStatus()); - self::assertEquals(4, $response->getHeader('Content-Length')); - }, function ($error) use ($request): void { + $this->assertEquals("foo\n", $response->getBody()); + $this->assertSame(200, $response->getStatus()); + $this->assertEquals(4, $response->getHeader('Content-Length')); + }, function ($error) use ($request): never { $url = $request->getUrl(); - self::fail("Failed to get $url"); + self::fail("Failed to get {$url}"); }); $url = $this->getAbsoluteUrl('/bar.php'); $request = new Request('GET', $url); $client->sendAsync($request, function (ResponseInterface $response): void { - self::assertEquals("bar\n", $response->getBody()); - self::assertEquals(200, $response->getStatus()); - self::assertEquals('Bar', $response->getHeader('X-Test')); - }, function ($error) use ($request): void { + $this->assertEquals("bar\n", $response->getBody()); + $this->assertSame(200, $response->getStatus()); + $this->assertSame('Bar', $response->getHeader('X-Test')); + }, function ($error) use ($request): never { $url = $request->getUrl(); - self::fail("Failed to get $url"); + self::fail("Failed to get {$url}"); }); $client->wait(); @@ -312,7 +305,7 @@ public function testSendClientError(): void $client = new ClientMock(); $request = new Request('GET', 'http://example.org/'); - $client->on('doRequest', function ($request, &$response): void { + $client->on('doRequest', function ($request, &$response): never { throw new ClientException('aaah', 1); }); $called = false; @@ -325,7 +318,8 @@ public function testSendClientError(): void self::fail('send() should have thrown an exception'); } catch (ClientException) { } - self::assertTrue($called); + + $this->assertTrue($called); } public function testSendHttpError(): void @@ -345,7 +339,7 @@ public function testSendHttpError(): void }); $client->send($request); - self::assertEquals(2, $called); + $this->assertSame(2, $called); } public function testSendRetry(): void @@ -356,11 +350,7 @@ public function testSendRetry(): void $called = 0; $client->on('doRequest', function ($request, &$response) use (&$called): void { ++$called; - if ($called < 3) { - $response = new Response(404); - } else { - $response = new Response(200); - } + $response = $called < 3 ? new Response(404) : new Response(200); }); $errorCalled = 0; @@ -370,15 +360,16 @@ public function testSendRetry(): void }); $response = $client->send($request); - self::assertEquals(3, $called); - self::assertEquals(2, $errorCalled); - self::assertEquals(200, $response->getStatus()); + $this->assertSame(3, $called); + $this->assertSame(2, $errorCalled); + $this->assertSame(200, $response->getStatus()); } public function testHttpErrorException(): void { $client = new ClientMock(); $client->setThrowExceptions(true); + $request = new Request('GET', 'http://example.org/'); $client->on('doRequest', function ($request, &$response): void { @@ -388,9 +379,9 @@ public function testHttpErrorException(): void try { $client->send($request); self::fail('An exception should have been thrown'); - } catch (ClientHttpException $e) { - self::assertEquals(404, $e->getHttpStatus()); - self::assertInstanceOf(Response::class, $e->getResponse()); + } catch (ClientHttpException $clientHttpException) { + $this->assertEquals(404, $clientHttpException->getHttpStatus()); + $this->assertInstanceOf(Response::class, $clientHttpException->getResponse()); } } @@ -412,11 +403,11 @@ public function testParseCurlResult(): void /** @phpstan-ignore-next-line */ $result = $client->parseCurlResult($body, 'foobar'); - self::assertEquals(Client::STATUS_SUCCESS, $result['status']); - self::assertEquals(200, $result['http_code']); - self::assertEquals(200, $result['response']->getStatus()); - self::assertEquals(['Header1' => ['Val1']], $result['response']->getHeaders()); - self::assertEquals('Foo', $result['response']->getBodyAsString()); + $this->assertEquals(Client::STATUS_SUCCESS, $result['status']); + $this->assertEquals(200, $result['http_code']); + $this->assertEquals(200, $result['response']->getStatus()); + $this->assertEquals(['Header1' => ['Val1']], $result['response']->getHeaders()); + $this->assertEquals('Foo', $result['response']->getBodyAsString()); } public function testParseCurlResultEmptyBody(): void @@ -437,11 +428,11 @@ public function testParseCurlResultEmptyBody(): void /** @phpstan-ignore-next-line */ $result = $client->parseCurlResult($body, 'foobar'); - self::assertEquals(Client::STATUS_SUCCESS, $result['status']); - self::assertEquals(200, $result['http_code']); - self::assertEquals(200, $result['response']->getStatus()); - self::assertEquals(['Header1' => ['Val1']], $result['response']->getHeaders()); - self::assertEquals('', $result['response']->getBodyAsString()); + $this->assertEquals(Client::STATUS_SUCCESS, $result['status']); + $this->assertEquals(200, $result['http_code']); + $this->assertEquals(200, $result['response']->getStatus()); + $this->assertEquals(['Header1' => ['Val1']], $result['response']->getHeaders()); + $this->assertEquals('', $result['response']->getBodyAsString()); } public function testParseCurlError(): void @@ -459,9 +450,9 @@ public function testParseCurlError(): void /** @phpstan-ignore-next-line */ $result = $client->parseCurlResult($body, 'foobar'); - self::assertEquals(Client::STATUS_CURLERROR, $result['status']); - self::assertEquals(1, $result['curl_errno']); - self::assertEquals('Curl error', $result['curl_errmsg']); + $this->assertEquals(Client::STATUS_CURLERROR, $result['status']); + $this->assertEquals(1, $result['curl_errno']); + $this->assertEquals('Curl error', $result['curl_errmsg']); } public function testDoRequest(): void @@ -482,9 +473,9 @@ public function testDoRequest(): void ]; }); $response = $client->doRequest($request); - self::assertEquals(200, $response->getStatus()); - self::assertEquals(['Header1' => ['Val1']], $response->getHeaders()); - self::assertEquals('Foo', $response->getBodyAsString()); + $this->assertSame(200, $response->getStatus()); + $this->assertSame(['Header1' => ['Val1']], $response->getHeaders()); + $this->assertSame('Foo', $response->getBodyAsString()); } public function testDoRequestCurlError(): void @@ -505,9 +496,9 @@ public function testDoRequestCurlError(): void try { $response = $client->doRequest($request); self::fail('This should have thrown an exception'); - } catch (ClientException $e) { - self::assertEquals(1, $e->getCode()); - self::assertEquals('Curl error', $e->getMessage()); + } catch (ClientException $clientException) { + $this->assertEquals(1, $clientException->getCode()); + $this->assertSame('Curl error', $clientException->getMessage()); } } } @@ -517,7 +508,7 @@ class ClientMock extends Client /** * Making this method public. */ - public function receiveCurlHeader($curlHandle, string $headerLine): int + protected function receiveCurlHeader($curlHandle, string $headerLine): int { return parent::receiveCurlHeader($curlHandle, $headerLine); } @@ -525,7 +516,7 @@ public function receiveCurlHeader($curlHandle, string $headerLine): int /** * Making this method public. */ - public function createCurlSettingsArray(RequestInterface $request): array + protected function createCurlSettingsArray(RequestInterface $request): array { return parent::createCurlSettingsArray($request); } @@ -533,7 +524,7 @@ public function createCurlSettingsArray(RequestInterface $request): array /** * Making this method public. */ - public function parseCurlResult(string $response, $curlHandle): array + protected function parseCurlResult(string $response, $curlHandle): array { return parent::parseCurlResult($response, $curlHandle); } @@ -541,7 +532,7 @@ public function parseCurlResult(string $response, $curlHandle): array /** * This method is responsible for performing a single request. */ - public function doRequest(RequestInterface $request): ResponseInterface + protected function doRequest(RequestInterface $request): ResponseInterface { $response = null; $this->emit('doRequest', [$request, &$response]); diff --git a/tests/HTTP/FunctionsTest.php b/tests/HTTP/FunctionsTest.php index 74af10e4..ea3fa325 100644 --- a/tests/HTTP/FunctionsTest.php +++ b/tests/HTTP/FunctionsTest.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\Attributes\DataProvider; -class FunctionsTest extends \PHPUnit\Framework\TestCase +final class FunctionsTest extends \PHPUnit\Framework\TestCase { /** * @param array $result @@ -16,25 +16,23 @@ class FunctionsTest extends \PHPUnit\Framework\TestCase #[DataProvider('getHeaderValuesDataOnValues2')] public function testGetHeaderValuesOnValues2(array $result, array $values1, array $values2): void { - self::assertEquals($result, getHeaderValues($values1, $values2)); + $this->assertEquals($result, getHeaderValues($values1, $values2)); } /** - * @return array>> + * @return \Iterator>> */ - public static function getHeaderValuesDataOnValues2(): array + public static function getHeaderValuesDataOnValues2(): \Iterator { - return [ - [ - ['a', 'b'], - ['a'], - ['b'], - ], - [ - ['a', 'b', 'c', 'd', 'e'], - ['a', 'b', 'c'], - ['d', 'e'], - ], + yield [ + ['a', 'b'], + ['a'], + ['b'], + ]; + yield [ + ['a', 'b', 'c', 'd', 'e'], + ['a', 'b', 'c'], + ['d', 'e'], ]; } @@ -43,40 +41,35 @@ public static function getHeaderValuesDataOnValues2(): array * @param array $output */ #[DataProvider('getHeaderValuesData')] - public function testGetHeaderValues($input, array $output): void + public function testGetHeaderValues(string|array $input, array $output): void { - self::assertEquals( - $output, - getHeaderValues($input) - ); + $this->assertEquals($output, getHeaderValues($input)); } /** - * @return array + * @return \Iterator */ - public static function getHeaderValuesData(): array + public static function getHeaderValuesData(): \Iterator { - return [ - [ - 'a', - ['a'], - ], - [ - 'a,b', - ['a', 'b'], - ], - [ - 'a, b', - ['a', 'b'], - ], - [ - ['a, b'], - ['a', 'b'], - ], - [ - ['a, b', 'c', 'd,e'], - ['a', 'b', 'c', 'd', 'e'], - ], + yield [ + 'a', + ['a'], + ]; + yield [ + 'a,b', + ['a', 'b'], + ]; + yield [ + 'a, b', + ['a', 'b'], + ]; + yield [ + ['a, b'], + ['a', 'b'], + ]; + yield [ + ['a, b', 'c', 'd,e'], + ['a', 'b', 'c', 'd', 'e'], ]; } @@ -85,70 +78,65 @@ public static function getHeaderValuesData(): array * @param array $output */ #[DataProvider('preferData')] - public function testPrefer($input, array $output): void + public function testPrefer(string|array $input, array $output): void { - self::assertEquals( - $output, - parsePrefer($input) - ); + $this->assertEquals($output, parsePrefer($input)); } /** - * @return array + * @return \Iterator */ - public static function preferData(): array + public static function preferData(): \Iterator { - return [ - [ - 'foo; bar', - ['foo' => true], - ], - [ - 'foo; bar=""', - ['foo' => true], - ], - [ - 'foo=""; bar', - ['foo' => true], - ], - [ - 'FOO', - ['foo' => true], - ], - [ - 'respond-async', - ['respond-async' => true], - ], - [ - ['respond-async, wait=100', 'handling=lenient'], - ['respond-async' => true, 'wait' => 100, 'handling' => 'lenient'], - ], - [ - ['respond-async, wait=100, handling=lenient'], - ['respond-async' => true, 'wait' => 100, 'handling' => 'lenient'], - ], - // Old values - [ - 'return-asynch, return-representation', - ['respond-async' => true, 'return' => 'representation'], - ], - [ - 'return-minimal', - ['return' => 'minimal'], - ], - [ - 'strict', - ['handling' => 'strict'], - ], - [ - 'lenient', - ['handling' => 'lenient'], - ], - // Invalid token - [ - ['foo=%bar%'], - [], - ], + yield [ + 'foo; bar', + ['foo' => true], + ]; + yield [ + 'foo; bar=""', + ['foo' => true], + ]; + yield [ + 'foo=""; bar', + ['foo' => true], + ]; + yield [ + 'FOO', + ['foo' => true], + ]; + yield [ + 'respond-async', + ['respond-async' => true], + ]; + yield [ + ['respond-async, wait=100', 'handling=lenient'], + ['respond-async' => true, 'wait' => 100, 'handling' => 'lenient'], + ]; + yield [ + ['respond-async, wait=100, handling=lenient'], + ['respond-async' => true, 'wait' => 100, 'handling' => 'lenient'], + ]; + // Old values + yield [ + 'return-asynch, return-representation', + ['respond-async' => true, 'return' => 'representation'], + ]; + yield [ + 'return-minimal', + ['return' => 'minimal'], + ]; + yield [ + 'strict', + ['handling' => 'strict'], + ]; + yield [ + 'lenient', + ['handling' => 'lenient'], + ]; + // Invalid token + yield [ + ['foo=%bar%'], + [], ]; } @@ -164,11 +152,11 @@ public function testParseHTTPDate(): void foreach ($times as $time) { $result = parseDate($time); - self::assertEquals($expected, $result->format('U')); + $this->assertEquals($expected, $result->format('U')); } $result = parseDate('Wed Oct 6 10:26:00 2010'); - self::assertEquals(1286360760, $result->format('U')); + $this->assertEquals(1286360760, $result->format('U')); } public function testParseHTTPDateFail(): void @@ -193,7 +181,7 @@ public function testParseHTTPDateFail(): void ]; foreach ($times as $time) { - self::assertFalse(parseDate($time), 'We used the string: '.$time); + $this->assertFalse(parseDate($time), 'We used the string: '.$time); } } @@ -211,10 +199,7 @@ public function testToHTTPDate(): void { $dt = new \DateTime('2011-12-10 12:00:00 +0200'); - self::assertEquals( - 'Sat, 10 Dec 2011 10:00:00 GMT', - toDate($dt) - ); + $this->assertSame('Sat, 10 Dec 2011 10:00:00 GMT', toDate($dt)); } public function testParseMimeTypeOnInvalidMimeType(): void diff --git a/tests/HTTP/MessageDecoratorTest.php b/tests/HTTP/MessageDecoratorTest.php index 6b58df59..1f74709e 100644 --- a/tests/HTTP/MessageDecoratorTest.php +++ b/tests/HTTP/MessageDecoratorTest.php @@ -4,12 +4,13 @@ namespace Sabre\HTTP; -class MessageDecoratorTest extends \PHPUnit\Framework\TestCase +final class MessageDecoratorTest extends \PHPUnit\Framework\TestCase { - protected Request $inner; - protected RequestDecorator $outer; + private Request $inner; - public function setUp(): void + private RequestDecorator $outer; + + protected function setUp(): void { $this->inner = new Request('GET', '/'); $this->outer = new RequestDecorator($this->inner); @@ -18,12 +19,12 @@ public function setUp(): void public function testBody(): void { $this->outer->setBody('foo'); - self::assertEquals('foo', stream_get_contents($this->inner->getBodyAsStream())); - self::assertEquals('foo', stream_get_contents($this->outer->getBodyAsStream())); - self::assertEquals('foo', $this->inner->getBodyAsString()); - self::assertEquals('foo', $this->outer->getBodyAsString()); - self::assertEquals('foo', $this->inner->getBody()); - self::assertEquals('foo', $this->outer->getBody()); + $this->assertEquals('foo', stream_get_contents($this->inner->getBodyAsStream())); + $this->assertEquals('foo', stream_get_contents($this->outer->getBodyAsStream())); + $this->assertSame('foo', $this->inner->getBodyAsString()); + $this->assertSame('foo', $this->outer->getBodyAsString()); + $this->assertEquals('foo', $this->inner->getBody()); + $this->assertEquals('foo', $this->outer->getBody()); } public function testHeaders(): void @@ -32,60 +33,54 @@ public function testHeaders(): void 'a' => 'b', ]); - self::assertEquals(['a' => ['b']], $this->inner->getHeaders()); - self::assertEquals(['a' => ['b']], $this->outer->getHeaders()); + $this->assertSame(['a' => ['b']], $this->inner->getHeaders()); + $this->assertSame(['a' => ['b']], $this->outer->getHeaders()); $this->outer->setHeaders([ 'c' => 'd', ]); - self::assertEquals(['a' => ['b'], 'c' => ['d']], $this->inner->getHeaders()); - self::assertEquals(['a' => ['b'], 'c' => ['d']], $this->outer->getHeaders()); + $this->assertSame(['a' => ['b'], 'c' => ['d']], $this->inner->getHeaders()); + $this->assertSame(['a' => ['b'], 'c' => ['d']], $this->outer->getHeaders()); $this->outer->addHeaders([ 'e' => 'f', ]); - self::assertEquals(['a' => ['b'], 'c' => ['d'], 'e' => ['f']], $this->inner->getHeaders()); - self::assertEquals(['a' => ['b'], 'c' => ['d'], 'e' => ['f']], $this->outer->getHeaders()); + $this->assertSame(['a' => ['b'], 'c' => ['d'], 'e' => ['f']], $this->inner->getHeaders()); + $this->assertSame(['a' => ['b'], 'c' => ['d'], 'e' => ['f']], $this->outer->getHeaders()); } public function testHeader(): void { - self::assertFalse($this->outer->hasHeader('a')); - self::assertFalse($this->inner->hasHeader('a')); + $this->assertFalse($this->outer->hasHeader('a')); + $this->assertFalse($this->inner->hasHeader('a')); $this->outer->setHeader('a', 'c'); - self::assertTrue($this->outer->hasHeader('a')); - self::assertTrue($this->inner->hasHeader('a')); + $this->assertTrue($this->outer->hasHeader('a')); + $this->assertTrue($this->inner->hasHeader('a')); - self::assertEquals('c', $this->inner->getHeader('A')); - self::assertEquals('c', $this->outer->getHeader('A')); + $this->assertSame('c', $this->inner->getHeader('A')); + $this->assertSame('c', $this->outer->getHeader('A')); $this->outer->addHeader('A', 'd'); - self::assertEquals( - ['c', 'd'], - $this->inner->getHeaderAsArray('A') - ); - self::assertEquals( - ['c', 'd'], - $this->outer->getHeaderAsArray('A') - ); + $this->assertSame(['c', 'd'], $this->inner->getHeaderAsArray('A')); + $this->assertSame(['c', 'd'], $this->outer->getHeaderAsArray('A')); $success = $this->outer->removeHeader('a'); - self::assertTrue($success); - self::assertNull($this->inner->getHeader('A')); - self::assertNull($this->outer->getHeader('A')); + $this->assertTrue($success); + $this->assertNull($this->inner->getHeader('A')); + $this->assertNull($this->outer->getHeader('A')); - self::assertFalse($this->outer->removeHeader('i-dont-exist')); + $this->assertFalse($this->outer->removeHeader('i-dont-exist')); } public function testHttpVersion(): void { $this->outer->setHttpVersion('1.0'); - self::assertEquals('1.0', $this->inner->getHttpVersion()); - self::assertEquals('1.0', $this->outer->getHttpVersion()); + $this->assertEquals('1.0', $this->inner->getHttpVersion()); + $this->assertEquals('1.0', $this->outer->getHttpVersion()); } } diff --git a/tests/HTTP/MessageTest.php b/tests/HTTP/MessageTest.php index 73952477..33accb02 100644 --- a/tests/HTTP/MessageTest.php +++ b/tests/HTTP/MessageTest.php @@ -4,12 +4,12 @@ namespace Sabre\HTTP; -class MessageTest extends \PHPUnit\Framework\TestCase +final class MessageTest extends \PHPUnit\Framework\TestCase { public function testConstruct(): void { $message = new MessageMock(); - self::assertInstanceOf(Message::class, $message); + $this->assertInstanceOf(Message::class, $message); } public function testStreamBody(): void @@ -22,11 +22,11 @@ public function testStreamBody(): void $message = new MessageMock(); $message->setBody($h); - self::assertEquals($body, $message->getBodyAsString()); + $this->assertSame($body, $message->getBodyAsString()); rewind($h); - self::assertEquals($body, stream_get_contents($message->getBodyAsStream())); + $this->assertEquals($body, stream_get_contents($message->getBodyAsStream())); rewind($h); - self::assertEquals($body, stream_get_contents($message->getBody())); + $this->assertEquals($body, stream_get_contents($message->getBody())); } public function testStringBody(): void @@ -36,9 +36,9 @@ public function testStringBody(): void $message = new MessageMock(); $message->setBody($body); - self::assertEquals($body, $message->getBodyAsString()); - self::assertEquals($body, stream_get_contents($message->getBodyAsStream())); - self::assertEquals($body, $message->getBody()); + $this->assertSame($body, $message->getBodyAsString()); + $this->assertEquals($body, stream_get_contents($message->getBodyAsStream())); + $this->assertEquals($body, $message->getBody()); } public function testCallbackBodyAsString(): void @@ -50,7 +50,7 @@ public function testCallbackBodyAsString(): void $string = $message->getBodyAsString(); - self::assertSame('foo', $string); + $this->assertSame('foo', $string); } public function testCallbackBodyAsStream(): void @@ -62,7 +62,7 @@ public function testCallbackBodyAsStream(): void $stream = $message->getBodyAsStream(); - self::assertSame('foo', stream_get_contents($stream)); + $this->assertSame('foo', stream_get_contents($stream)); } public function testGetBodyWhenCallback(): void @@ -72,7 +72,7 @@ public function testGetBodyWhenCallback(): void $message = new MessageMock(); $message->setBody($callback); - self::assertSame($callback, $message->getBody()); + $this->assertSame($callback, $message->getBody()); } /** @@ -96,10 +96,7 @@ public function testLongStreamToStringBody(): void $message->setBody($body); $message->setHeader('Content-Length', '4'); - self::assertEquals( - 'cdef', - $message->getBodyAsString() - ); + $this->assertSame('cdef', $message->getBodyAsString()); } /** @@ -116,10 +113,7 @@ public function testEmptyContentLengthHeader(): void $message->setBody($body); $message->setHeader('Content-Length', ''); - self::assertEquals( - 'cdefg', - $message->getBodyAsString() - ); + $this->assertSame('cdefg', $message->getBodyAsString()); } public function testGetEmptyBodyStream(): void @@ -127,7 +121,7 @@ public function testGetEmptyBodyStream(): void $message = new MessageMock(); $body = $message->getBodyAsStream(); - self::assertEquals('', stream_get_contents($body)); + $this->assertEquals('', stream_get_contents($body)); } public function testGetEmptyBodyString(): void @@ -135,7 +129,7 @@ public function testGetEmptyBodyString(): void $message = new MessageMock(); $body = $message->getBodyAsString(); - self::assertEquals('', $body); + $this->assertSame('', $body); } public function testHeaders(): void @@ -144,16 +138,12 @@ public function testHeaders(): void $message->setHeader('X-Foo', 'bar'); // Testing caselessness - self::assertEquals('bar', $message->getHeader('X-Foo')); - self::assertEquals('bar', $message->getHeader('x-fOO')); - - self::assertTrue( - $message->removeHeader('X-FOO') - ); - self::assertNull($message->getHeader('X-Foo')); - self::assertFalse( - $message->removeHeader('X-FOO') - ); + $this->assertSame('bar', $message->getHeader('X-Foo')); + $this->assertSame('bar', $message->getHeader('x-fOO')); + + $this->assertTrue($message->removeHeader('X-FOO')); + $this->assertNull($message->getHeader('X-Foo')); + $this->assertFalse($message->removeHeader('X-FOO')); } public function testSetHeaders(): void @@ -166,7 +156,7 @@ public function testSetHeaders(): void ]; $message->setHeaders($headers); - self::assertEquals($headers, $message->getHeaders()); + $this->assertSame($headers, $message->getHeaders()); $message->setHeaders([ 'X-Foo' => ['3', '4'], @@ -178,7 +168,7 @@ public function testSetHeaders(): void 'X-Bar' => ['5'], ]; - self::assertEquals($expected, $message->getHeaders()); + $this->assertSame($expected, $message->getHeaders()); } public function testAddHeaders(): void @@ -191,7 +181,7 @@ public function testAddHeaders(): void ]; $message->addHeaders($headers); - self::assertEquals($headers, $message->getHeaders()); + $this->assertSame($headers, $message->getHeaders()); $message->addHeaders([ 'X-Foo' => ['3', '4'], @@ -203,7 +193,7 @@ public function testAddHeaders(): void 'X-Bar' => ['2', '5'], ]; - self::assertEquals($expected, $message->getHeaders()); + $this->assertSame($expected, $message->getHeaders()); } public function testSendBody(): void @@ -222,7 +212,7 @@ public function testSendBody(): void $body = $message->getBody(); rewind($body); - self::assertEquals('bar', stream_get_contents($body)); + $this->assertEquals('bar', stream_get_contents($body)); } public function testMultipleHeaders(): void @@ -231,44 +221,27 @@ public function testMultipleHeaders(): void $message->setHeader('a', '1'); $message->addHeader('A', '2'); - self::assertEquals( - '1,2', - $message->getHeader('A') - ); - self::assertEquals( - '1,2', - $message->getHeader('a') - ); - - self::assertEquals( - ['1', '2'], - $message->getHeaderAsArray('a') - ); - self::assertEquals( - ['1', '2'], - $message->getHeaderAsArray('A') - ); - self::assertEquals( - [], - $message->getHeaderAsArray('B') - ); + $this->assertSame('1,2', $message->getHeader('A')); + $this->assertSame('1,2', $message->getHeader('a')); + + $this->assertSame(['1', '2'], $message->getHeaderAsArray('a')); + $this->assertSame(['1', '2'], $message->getHeaderAsArray('A')); + $this->assertSame([], $message->getHeaderAsArray('B')); } public function testHasHeaders(): void { $message = new MessageMock(); - self::assertFalse($message->hasHeader('X-Foo')); + $this->assertFalse($message->hasHeader('X-Foo')); $message->setHeader('X-Foo', 'Bar'); - self::assertTrue($message->hasHeader('X-Foo')); + $this->assertTrue($message->hasHeader('X-Foo')); } /** - * @param string $content - * * @return \Closure Returns a callback printing $content to php://output stream */ - private function createCallback($content) + private function createCallback(string $content) { return function () use ($content): void { echo $content; diff --git a/tests/HTTP/NegotiateTest.php b/tests/HTTP/NegotiateTest.php index 1a2e0699..d111205d 100644 --- a/tests/HTTP/NegotiateTest.php +++ b/tests/HTTP/NegotiateTest.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\Attributes\DataProvider; -class NegotiateTest extends \PHPUnit\Framework\TestCase +final class NegotiateTest extends \PHPUnit\Framework\TestCase { /** * @param array $available @@ -14,128 +14,123 @@ class NegotiateTest extends \PHPUnit\Framework\TestCase #[DataProvider('negotiateData')] public function testNegotiate(?string $acceptHeader, array $available, ?string $expected): void { - self::assertEquals( - $expected, - negotiateContentType($acceptHeader, $available) - ); + $this->assertEquals($expected, negotiateContentType($acceptHeader, $available)); } /** - * @return array> + * @return \Iterator> */ - public static function negotiateData(): array + public static function negotiateData(): \Iterator { - return [ - [ // simple - 'application/xml', - ['application/xml'], - 'application/xml', - ], - [ // no header - null, - ['application/xml'], - 'application/xml', - ], - [ // 2 options - 'application/json', - ['application/xml', 'application/json'], - 'application/json', - ], - [ // 2 choices - 'application/json, application/xml', - ['application/xml'], - 'application/xml', - ], - [ // quality - 'application/xml;q=0.2, application/json', - ['application/xml', 'application/json'], - 'application/json', - ], - [ // wildcard - 'image/jpeg, image/png, */*', - ['application/xml', 'application/json'], - 'application/xml', - ], - [ // wildcard + quality - 'image/jpeg, image/png; q=0.5, */*', - ['application/xml', 'application/json', 'image/png'], - 'application/xml', - ], - [ // no match - 'image/jpeg', - ['application/xml'], - null, - ], - [ // This is used in sabre/dav - 'text/vcard; version=4.0', - [ - // Most often used mime-type. Version 3 - 'text/x-vcard', - // The correct standard mime-type. Defaults to version 3 as - // well. - 'text/vcard', - // vCard 4 - 'text/vcard; version=4.0', - // vCard 3 - 'text/vcard; version=3.0', - // jCard - 'application/vcard+json', - ], + yield [ // simple + 'application/xml', + ['application/xml'], + 'application/xml', + ]; + yield [ // no header + null, + ['application/xml'], + 'application/xml', + ]; + yield [ // 2 options + 'application/json', + ['application/xml', 'application/json'], + 'application/json', + ]; + yield [ // 2 choices + 'application/json, application/xml', + ['application/xml'], + 'application/xml', + ]; + yield [ // quality + 'application/xml;q=0.2, application/json', + ['application/xml', 'application/json'], + 'application/json', + ]; + yield [ // wildcard + 'image/jpeg, image/png, */*', + ['application/xml', 'application/json'], + 'application/xml', + ]; + yield [ // wildcard + quality + 'image/jpeg, image/png; q=0.5, */*', + ['application/xml', 'application/json', 'image/png'], + 'application/xml', + ]; + yield [ // no match + 'image/jpeg', + ['application/xml'], + null, + ]; + yield [ // This is used in sabre/dav + 'text/vcard; version=4.0', + [ + // Most often used mime-type. Version 3 + 'text/x-vcard', + // The correct standard mime-type. Defaults to version 3 as + // well. + 'text/vcard', + // vCard 4 'text/vcard; version=4.0', + // vCard 3 + 'text/vcard; version=3.0', + // jCard + 'application/vcard+json', ], - [ // rfc7231 example 1 - 'audio/*; q=0.2, audio/basic', - [ - 'audio/pcm', - 'audio/basic', - ], + 'text/vcard; version=4.0', + ]; + yield [ // rfc7231 example 1 + 'audio/*; q=0.2, audio/basic', + [ + 'audio/pcm', 'audio/basic', ], - [ // Lower quality after - 'audio/pcm; q=0.2, audio/basic; q=0.1', - [ - 'audio/pcm', - 'audio/basic', - ], + 'audio/basic', + ]; + yield [ // Lower quality after + 'audio/pcm; q=0.2, audio/basic; q=0.1', + [ 'audio/pcm', + 'audio/basic', ], - [ // Random parameter, should be ignored - 'audio/pcm; hello; q=0.2, audio/basic; q=0.1', - [ - 'audio/pcm', - 'audio/basic', - ], + 'audio/pcm', + ]; + yield [ // Random parameter, should be ignored + 'audio/pcm; hello; q=0.2, audio/basic; q=0.1', + [ 'audio/pcm', + 'audio/basic', ], - [ // No whitespace after type, should pick the one that is the most specific. - 'text/vcard;version=3.0, text/vcard', - [ - 'text/vcard', - 'text/vcard; version=3.0', - ], + 'audio/pcm', + ]; + yield [ // No whitespace after type, should pick the one that is the most specific. + 'text/vcard;version=3.0, text/vcard', + [ + 'text/vcard', 'text/vcard; version=3.0', ], - [ // Same as last one, but order is different - 'text/vcard, text/vcard;version=3.0', - [ - 'text/vcard; version=3.0', - 'text/vcard', - ], + 'text/vcard; version=3.0', + ]; + yield [ // Same as last one, but order is different + 'text/vcard, text/vcard;version=3.0', + [ 'text/vcard; version=3.0', + 'text/vcard', ], - [ // Charset should be ignored here. - 'text/vcard; charset=utf-8; version=3.0, text/vcard', - [ - 'text/vcard', - 'text/vcard; version=3.0', - ], + 'text/vcard; version=3.0', + ]; + yield [ // Charset should be ignored here. + 'text/vcard; charset=utf-8; version=3.0, text/vcard', + [ + 'text/vcard', 'text/vcard; version=3.0', ], - [ // Undefined offset issue. - 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2', - ['application/xml', 'application/json', 'image/png'], - 'application/xml', - ], + 'text/vcard; version=3.0', + ]; + yield [ // Undefined offset issue. + 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2', + ['application/xml', 'application/json', 'image/png'], + 'application/xml', ]; } } diff --git a/tests/HTTP/RequestDecoratorTest.php b/tests/HTTP/RequestDecoratorTest.php index a6f661af..bcda1892 100644 --- a/tests/HTTP/RequestDecoratorTest.php +++ b/tests/HTTP/RequestDecoratorTest.php @@ -4,12 +4,13 @@ namespace Sabre\HTTP; -class RequestDecoratorTest extends \PHPUnit\Framework\TestCase +final class RequestDecoratorTest extends \PHPUnit\Framework\TestCase { - protected Request $inner; - protected RequestDecorator $outer; + private Request $inner; - public function setUp(): void + private RequestDecorator $outer; + + protected function setUp(): void { $this->inner = new Request('GET', '/'); $this->outer = new RequestDecorator($this->inner); @@ -18,37 +19,37 @@ public function setUp(): void public function testMethod(): void { $this->outer->setMethod('FOO'); - self::assertEquals('FOO', $this->inner->getMethod()); - self::assertEquals('FOO', $this->outer->getMethod()); + $this->assertSame('FOO', $this->inner->getMethod()); + $this->assertSame('FOO', $this->outer->getMethod()); } public function testUrl(): void { $this->outer->setUrl('/foo'); - self::assertEquals('/foo', $this->inner->getUrl()); - self::assertEquals('/foo', $this->outer->getUrl()); + $this->assertSame('/foo', $this->inner->getUrl()); + $this->assertSame('/foo', $this->outer->getUrl()); } public function testAbsoluteUrl(): void { $this->outer->setAbsoluteUrl('http://example.org/foo'); - self::assertEquals('http://example.org/foo', $this->inner->getAbsoluteUrl()); - self::assertEquals('http://example.org/foo', $this->outer->getAbsoluteUrl()); + $this->assertSame('http://example.org/foo', $this->inner->getAbsoluteUrl()); + $this->assertSame('http://example.org/foo', $this->outer->getAbsoluteUrl()); } public function testBaseUrl(): void { $this->outer->setBaseUrl('/foo'); - self::assertEquals('/foo', $this->inner->getBaseUrl()); - self::assertEquals('/foo', $this->outer->getBaseUrl()); + $this->assertSame('/foo', $this->inner->getBaseUrl()); + $this->assertSame('/foo', $this->outer->getBaseUrl()); } public function testPath(): void { $this->outer->setBaseUrl('/foo'); $this->outer->setUrl('/foo/bar'); - self::assertEquals('bar', $this->inner->getPath()); - self::assertEquals('bar', $this->outer->getPath()); + $this->assertSame('bar', $this->inner->getPath()); + $this->assertSame('bar', $this->outer->getPath()); } public function testQueryParams(): void @@ -60,8 +61,8 @@ public function testQueryParams(): void 'e' => null, ]; - self::assertEquals($expected, $this->inner->getQueryParameters()); - self::assertEquals($expected, $this->outer->getQueryParameters()); + $this->assertEquals($expected, $this->inner->getQueryParameters()); + $this->assertEquals($expected, $this->outer->getQueryParameters()); } public function testPostData(): void @@ -73,8 +74,8 @@ public function testPostData(): void ]; $this->outer->setPostData($postData); - self::assertEquals($postData, $this->inner->getPostData()); - self::assertEquals($postData, $this->outer->getPostData()); + $this->assertEquals($postData, $this->inner->getPostData()); + $this->assertEquals($postData, $this->outer->getPostData()); } public function testServerData(): void @@ -84,11 +85,11 @@ public function testServerData(): void ]; $this->outer->setRawServerData($serverData); - self::assertEquals('On', $this->inner->getRawServerValue('HTTPS')); - self::assertEquals('On', $this->outer->getRawServerValue('HTTPS')); + $this->assertSame('On', $this->inner->getRawServerValue('HTTPS')); + $this->assertSame('On', $this->outer->getRawServerValue('HTTPS')); - self::assertNull($this->inner->getRawServerValue('FOO')); - self::assertNull($this->outer->getRawServerValue('FOO')); + $this->assertNull($this->inner->getRawServerValue('FOO')); + $this->assertNull($this->outer->getRawServerValue('FOO')); } public function testToString(): void @@ -98,6 +99,6 @@ public function testToString(): void $this->inner->setBody('foo'); $this->inner->setHeader('foo', 'bar'); - self::assertEquals((string) $this->inner, (string) $this->outer); + $this->assertSame((string) $this->inner, (string) $this->outer); } } diff --git a/tests/HTTP/RequestTest.php b/tests/HTTP/RequestTest.php index 2e154b4c..eb4cebae 100644 --- a/tests/HTTP/RequestTest.php +++ b/tests/HTTP/RequestTest.php @@ -4,16 +4,16 @@ namespace Sabre\HTTP; -class RequestTest extends \PHPUnit\Framework\TestCase +final class RequestTest extends \PHPUnit\Framework\TestCase { public function testConstruct(): void { $request = new Request('GET', '/foo', [ 'User-Agent' => 'Evert', ]); - self::assertEquals('GET', $request->getMethod()); - self::assertEquals('/foo', $request->getUrl()); - self::assertEquals([ + $this->assertSame('GET', $request->getMethod()); + $this->assertSame('/foo', $request->getUrl()); + $this->assertSame([ 'User-Agent' => ['Evert'], ], $request->getHeaders()); } @@ -21,7 +21,7 @@ public function testConstruct(): void public function testGetQueryParameters(): void { $request = new Request('GET', '/foo?a=b&c&d=e'); - self::assertEquals([ + $this->assertEquals([ 'a' => 'b', 'c' => null, 'd' => 'e', @@ -31,7 +31,7 @@ public function testGetQueryParameters(): void public function testGetQueryParametersNoData(): void { $request = new Request('GET', '/foo'); - self::assertEquals([], $request->getQueryParameters()); + $this->assertSame([], $request->getQueryParameters()); } /** @@ -43,7 +43,7 @@ public function testCreateFromPHPRequest(): void $_SERVER['REQUEST_METHOD'] = 'PUT'; $request = Sapi::getRequest(); - self::assertEquals('PUT', $request->getMethod()); + $this->assertSame('PUT', $request->getMethod()); } public function testGetAbsoluteUrl(): void @@ -52,7 +52,7 @@ public function testGetAbsoluteUrl(): void 'Host' => 'sabredav.org', ]); - self::assertEquals('http://sabredav.org/foo', $r->getAbsoluteUrl()); + $this->assertSame('http://sabredav.org/foo', $r->getAbsoluteUrl()); $s = [ 'HTTP_HOST' => 'sabredav.org', @@ -63,7 +63,7 @@ public function testGetAbsoluteUrl(): void $r = Sapi::createFromServerArray($s); - self::assertEquals('https://sabredav.org/foo', $r->getAbsoluteUrl()); + $this->assertSame('https://sabredav.org/foo', $r->getAbsoluteUrl()); } public function testGetPostData(): void @@ -73,7 +73,7 @@ public function testGetPostData(): void ]; $r = new Request('POST', '/'); $r->setPostData($post); - self::assertEquals($post, $r->getPostData()); + $this->assertSame($post, $r->getPostData()); } public function testGetPath(): void @@ -82,7 +82,7 @@ public function testGetPath(): void $request->setBaseUrl('/foo'); $request->setUrl('/foo/bar/'); - self::assertEquals('bar', $request->getPath()); + $this->assertSame('bar', $request->getPath()); } public function testGetPathStrippedQuery(): void @@ -90,7 +90,7 @@ public function testGetPathStrippedQuery(): void $request = new Request('GET', '/foo/bar?a=B'); $request->setBaseUrl('/foo'); - self::assertEquals('bar', $request->getPath()); + $this->assertSame('bar', $request->getPath()); } public function testGetPathMissingSlash(): void @@ -98,7 +98,7 @@ public function testGetPathMissingSlash(): void $request = new Request('GET', '/foo'); $request->setBaseUrl('/foo/'); - self::assertEquals('', $request->getPath()); + $this->assertSame('', $request->getPath()); } public function testGetPathOutsideBaseUrl(): void @@ -119,7 +119,7 @@ public function testToString(): void ."Content-Type: text/xml\r\n" ."\r\n" .'foo'; - self::assertEquals($expected, (string) $request); + $this->assertSame($expected, (string) $request); } public function testToStringAuthorization(): void @@ -132,13 +132,13 @@ public function testToStringAuthorization(): void ."Authorization: Basic REDACTED\r\n" ."\r\n" .'foo'; - self::assertEquals($expected, (string) $request); + $this->assertSame($expected, (string) $request); } public function testAbsoluteUrlHttp(): void { $request = new Request('GET', 'http://example.com/foo/bar?a=b&c=d'); - self::assertEquals('http://example.com/foo/bar?a=b&c=d', $request->getAbsoluteUrl()); + $this->assertSame('http://example.com/foo/bar?a=b&c=d', $request->getAbsoluteUrl()); } public function testAbsoluteUrlHttpHostPrevalence(): void @@ -146,6 +146,6 @@ public function testAbsoluteUrlHttpHostPrevalence(): void $request = new Request('GET', 'http://example.com/foo/bar?a=b&c=d', [ 'Host' => 'example.org', ]); - self::assertEquals('http://example.com/foo/bar?a=b&c=d', $request->getAbsoluteUrl()); + $this->assertSame('http://example.com/foo/bar?a=b&c=d', $request->getAbsoluteUrl()); } } diff --git a/tests/HTTP/ResponseDecoratorTest.php b/tests/HTTP/ResponseDecoratorTest.php index 1d16da13..34f6c38a 100644 --- a/tests/HTTP/ResponseDecoratorTest.php +++ b/tests/HTTP/ResponseDecoratorTest.php @@ -4,12 +4,13 @@ namespace Sabre\HTTP; -class ResponseDecoratorTest extends \PHPUnit\Framework\TestCase +final class ResponseDecoratorTest extends \PHPUnit\Framework\TestCase { - protected Response $inner; - protected ResponseDecorator $outer; + private Response $inner; - public function setUp(): void + private ResponseDecorator $outer; + + protected function setUp(): void { $this->inner = new Response(); $this->outer = new ResponseDecorator($this->inner); @@ -18,10 +19,10 @@ public function setUp(): void public function testStatus(): void { $this->outer->setStatus(201); - self::assertEquals(201, $this->inner->getStatus()); - self::assertEquals(201, $this->outer->getStatus()); - self::assertEquals('Created', $this->inner->getStatusText()); - self::assertEquals('Created', $this->outer->getStatusText()); + $this->assertSame(201, $this->inner->getStatus()); + $this->assertSame(201, $this->outer->getStatus()); + $this->assertSame('Created', $this->inner->getStatusText()); + $this->assertSame('Created', $this->outer->getStatusText()); } public function testToString(): void @@ -30,6 +31,6 @@ public function testToString(): void $this->inner->setBody('foo'); $this->inner->setHeader('foo', 'bar'); - self::assertEquals((string) $this->inner, (string) $this->outer); + $this->assertSame((string) $this->inner, (string) $this->outer); } } diff --git a/tests/HTTP/ResponseTest.php b/tests/HTTP/ResponseTest.php index 042b7e93..a88842cb 100644 --- a/tests/HTTP/ResponseTest.php +++ b/tests/HTTP/ResponseTest.php @@ -4,35 +4,35 @@ namespace Sabre\HTTP; -class ResponseTest extends \PHPUnit\Framework\TestCase +final class ResponseTest extends \PHPUnit\Framework\TestCase { public function testConstruct(): void { $response = new Response(200, ['Content-Type' => 'text/xml']); - self::assertEquals(200, $response->getStatus()); - self::assertEquals('OK', $response->getStatusText()); + $this->assertSame(200, $response->getStatus()); + $this->assertSame('OK', $response->getStatusText()); } public function testSetStatus(): void { $response = new Response(); - $response->setStatus('402 Where\'s my money?'); - self::assertEquals(402, $response->getStatus()); - self::assertEquals('Where\'s my money?', $response->getStatusText()); + $response->setStatus("402 Where's my money?"); + $this->assertSame(402, $response->getStatus()); + $this->assertSame("Where's my money?", $response->getStatusText()); } public function testSetStatusWithoutText(): void { $response = new Response(); $response->setStatus('402'); - self::assertEquals(402, $response->getStatus()); - self::assertEquals('Payment Required', $response->getStatusText()); + $this->assertSame(402, $response->getStatus()); + $this->assertSame('Payment Required', $response->getStatusText()); } public function testInvalidStatus(): void { $this->expectException('InvalidArgumentException'); - $response = new Response(1000); + new Response(1000); } public function testToString(): void @@ -44,6 +44,6 @@ public function testToString(): void ."Content-Type: text/xml\r\n" ."\r\n" .'foo'; - self::assertEquals($expected, (string) $response); + $this->assertSame($expected, (string) $response); } } diff --git a/tests/HTTP/SapiTest.php b/tests/HTTP/SapiTest.php index 9eb20085..6470f1c6 100644 --- a/tests/HTTP/SapiTest.php +++ b/tests/HTTP/SapiTest.php @@ -7,7 +7,7 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Depends; -class SapiTest extends \PHPUnit\Framework\TestCase +final class SapiTest extends \PHPUnit\Framework\TestCase { public function testConstructFromServerArray(): void { @@ -20,18 +20,18 @@ public function testConstructFromServerArray(): void 'SERVER_PROTOCOL' => 'HTTP/1.0', ]); - self::assertEquals('GET', $request->getMethod()); - self::assertEquals('/foo', $request->getUrl()); - self::assertEquals([ + $this->assertSame('GET', $request->getMethod()); + $this->assertSame('/foo', $request->getUrl()); + $this->assertSame([ 'User-Agent' => ['Evert'], 'Content-Type' => ['text/xml'], 'Content-Length' => ['400'], ], $request->getHeaders()); - self::assertEquals('1.0', $request->getHttpVersion()); + $this->assertEquals('1.0', $request->getHttpVersion()); - self::assertEquals('400', $request->getRawServerValue('CONTENT_LENGTH')); - self::assertNull($request->getRawServerValue('FOO')); + $this->assertEquals('400', $request->getRawServerValue('CONTENT_LENGTH')); + $this->assertNull($request->getRawServerValue('FOO')); } public function testConstructFromServerArrayOnNullUrl(): void @@ -39,7 +39,7 @@ public function testConstructFromServerArrayOnNullUrl(): void $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('The _SERVER array must have a REQUEST_URI key'); - $request = Sapi::createFromServerArray([ + Sapi::createFromServerArray([ 'REQUEST_METHOD' => 'GET', 'HTTP_USER_AGENT' => 'Evert', 'CONTENT_TYPE' => 'text/xml', @@ -53,7 +53,7 @@ public function testConstructFromServerArrayOnNullMethod(): void $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('The _SERVER array must have a REQUEST_METHOD key'); - $request = Sapi::createFromServerArray([ + Sapi::createFromServerArray([ 'REQUEST_URI' => '/foo', 'HTTP_USER_AGENT' => 'Evert', 'CONTENT_TYPE' => 'text/xml', @@ -71,9 +71,9 @@ public function testConstructPHPAuth(): void 'PHP_AUTH_PW' => 'pass', ]); - self::assertEquals('GET', $request->getMethod()); - self::assertEquals('/foo', $request->getUrl()); - self::assertEquals([ + $this->assertSame('GET', $request->getMethod()); + $this->assertSame('/foo', $request->getUrl()); + $this->assertEquals([ 'Authorization' => ['Basic '.base64_encode('user:pass')], ], $request->getHeaders()); } @@ -86,9 +86,9 @@ public function testConstructPHPAuthDigest(): void 'PHP_AUTH_DIGEST' => 'blabla', ]); - self::assertEquals('GET', $request->getMethod()); - self::assertEquals('/foo', $request->getUrl()); - self::assertEquals([ + $this->assertSame('GET', $request->getMethod()); + $this->assertSame('/foo', $request->getUrl()); + $this->assertSame([ 'Authorization' => ['Digest blabla'], ], $request->getHeaders()); } @@ -101,9 +101,9 @@ public function testConstructRedirectAuth(): void 'REDIRECT_HTTP_AUTHORIZATION' => 'Basic bla', ]); - self::assertEquals('GET', $request->getMethod()); - self::assertEquals('/foo', $request->getUrl()); - self::assertEquals([ + $this->assertSame('GET', $request->getMethod()); + $this->assertSame('/foo', $request->getUrl()); + $this->assertSame([ 'Authorization' => ['Basic bla'], ], $request->getHeaders()); } @@ -134,15 +134,12 @@ public function testSend(): void $result = ob_get_clean(); header_remove(); - self::assertEquals( - [ - 'Content-Type: text/xml;charset=UTF-8', - 'Content-Type: application/xml', - ], - $headers - ); + $this->assertSame([ + 'Content-Type: text/xml;charset=UTF-8', + 'Content-Type: application/xml', + ], $headers); - self::assertEquals('foo', $result); + $this->assertEquals('foo', $result); } /** @@ -163,7 +160,7 @@ public function testSendLimitedByContentLengthString(): void $result = ob_get_clean(); header_remove(); - self::assertEquals('Send this sentence.', $result); + $this->assertEquals('Send this sentence.', $result); } /** @@ -177,7 +174,7 @@ public function testRecognizeHttp2(): void 'REQUEST_METHOD' => 'GET', ]); - self::assertEquals('2.0', $request->getHttpVersion()); + $this->assertEquals('2.0', $request->getHttpVersion()); } /** @@ -201,7 +198,7 @@ public function testSendLimitedByContentLengthStream(): void $result = ob_get_clean(); header_remove(); - self::assertEquals('Send this sentence.', $result); + $this->assertEquals('Send this sentence.', $result); } /** @@ -223,15 +220,18 @@ public function testSendContentRangeStream( if (null === $contentLength) { $contentLength = strlen($partial); } + fwrite($body, $ignoreAtStart); fwrite($body, $partial); if ($ignoreAtEndLength > 0) { fwrite($body, $ignoreAtEnd); } + rewind($body); if ($ignoreAtStartLength > 0) { fread($body, $ignoreAtStartLength); } + $response = new Response(200, [ 'Content-Length' => $contentLength, 'Content-Range' => sprintf('bytes %d-%d/%d', $ignoreAtStartLength, $ignoreAtStartLength + strlen($partial) - 1, $ignoreAtStartLength + strlen($partial) + $ignoreAtEndLength), @@ -245,37 +245,34 @@ public function testSendContentRangeStream( $result = ob_get_clean(); header_remove(); - self::assertEquals($partial, $result); + $this->assertEquals($partial, $result); } /** - * @return array> + * @return \Iterator> */ - public static function sendContentRangeStreamData(): array + public static function sendContentRangeStreamData(): \Iterator { - return [ - ['Ignore this. ', 'Send this.', 10, ' Ignore this at end.'], - ['Ignore this. ', 'Send this.', 1000, ' Ignore this at end.'], - ['Ignore this. ', 'S', 4096, ' Ignore this at end.'], - ['I', 'S', 4094, 'E'], - ['', 'Send this.', 10, ' Ignore this at end.'], - ['', 'Send this.', 1000, ' Ignore this at end.'], - ['', 'S', 4096, ' Ignore this at end.'], - ['', 'S', 4094, 'En'], - ['Ignore this. ', 'Send this.', 10, ''], - ['Ignore this. ', 'Send this.', 1000, ''], - ['Ignore this. ', 'S', 4096, ''], - ['Ig', 'S', 4094, ''], - - // Provide contentLength greater than the bytes remaining in the stream. - ['Ignore this. ', 'Send this.', 10, '', 101], - ['Ignore this. ', 'Send this.', 1000, '', 10001], - ['Ignore this. ', 'S', 4096, '', 5000000], - ['I', 'S', 4094, '', 8095], - // Provide contentLength equal to the bytes remaining in the stream. - ['', 'Send this.', 10, '', 100], - ['Ignore this. ', 'Send this.', 1000, '', 10000], - ]; + yield ['Ignore this. ', 'Send this.', 10, ' Ignore this at end.']; + yield ['Ignore this. ', 'Send this.', 1000, ' Ignore this at end.']; + yield ['Ignore this. ', 'S', 4096, ' Ignore this at end.']; + yield ['I', 'S', 4094, 'E']; + yield ['', 'Send this.', 10, ' Ignore this at end.']; + yield ['', 'Send this.', 1000, ' Ignore this at end.']; + yield ['', 'S', 4096, ' Ignore this at end.']; + yield ['', 'S', 4094, 'En']; + yield ['Ignore this. ', 'Send this.', 10, '']; + yield ['Ignore this. ', 'Send this.', 1000, '']; + yield ['Ignore this. ', 'S', 4096, '']; + yield ['Ig', 'S', 4094, '']; + // Provide contentLength greater than the bytes remaining in the stream. + yield ['Ignore this. ', 'Send this.', 10, '', 101]; + yield ['Ignore this. ', 'Send this.', 1000, '', 10001]; + yield ['Ignore this. ', 'S', 4096, '', 5000000]; + yield ['I', 'S', 4094, '', 8095]; + // Provide contentLength equal to the bytes remaining in the stream. + yield ['', 'Send this.', 10, '', 100]; + yield ['Ignore this. ', 'Send this.', 1000, '', 10000]; } /** @@ -296,7 +293,7 @@ public function testSendWorksWithCallbackAsBody(): void $result = ob_get_clean(); - self::assertEquals('foo', $result); + $this->assertEquals('foo', $result); } public function testSendConnectionAborted(): void @@ -318,6 +315,7 @@ public function testSendConnectionAborted(): void if (false === $temp) { break; } + $size += strlen($temp); } @@ -326,7 +324,7 @@ public function testSendConnectionAborted(): void sleep(5); $bytes_read = file_get_contents(sys_get_temp_dir().'/dummy_stream_read_counter'); - self::assertEquals($chunk_size * 2, $bytes_read); - self::assertGreaterThanOrEqual($fetch_size, $bytes_read); + $this->assertEquals($chunk_size * 2, $bytes_read); + $this->assertGreaterThanOrEqual($fetch_size, $bytes_read); } } diff --git a/tests/HTTP/URLUtilTest.php b/tests/HTTP/URLUtilTest.php index 0ec65642..f63b7e96 100644 --- a/tests/HTTP/URLUtilTest.php +++ b/tests/HTTP/URLUtilTest.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\Attributes\Depends; -class URLUtilTest extends \PHPUnit\Framework\TestCase +final class URLUtilTest extends \PHPUnit\Framework\TestCase { public function testEncodePath(): void { @@ -17,18 +17,16 @@ public function testEncodePath(): void $newStr = encodePath($str); - self::assertEquals( - '%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f'. - '%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f'. - '%20%21%22%23%24%25%26%27()%2a%2b%2c-./'. - '0123456789:%3b%3c%3d%3e%3f'. - '@ABCDEFGHIJKLMNO'. - 'PQRSTUVWXYZ%5b%5c%5d%5e_'. - '%60abcdefghijklmno'. - 'pqrstuvwxyz%7b%7c%7d~%7f', - $newStr); - - self::assertEquals($str, decodePath($newStr)); + $this->assertSame('%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f'. + '%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f'. + '%20%21%22%23%24%25%26%27()%2a%2b%2c-./'. + '0123456789:%3b%3c%3d%3e%3f'. + '@ABCDEFGHIJKLMNO'. + 'PQRSTUVWXYZ%5b%5c%5d%5e_'. + '%60abcdefghijklmno'. + 'pqrstuvwxyz%7b%7c%7d~%7f', $newStr); + + $this->assertSame($str, decodePath($newStr)); } public function testEncodePathSegment(): void @@ -42,25 +40,23 @@ public function testEncodePathSegment(): void // Note: almost exactly the same as the last test, except for // the encoding of / (ascii code 2f) - self::assertEquals( - '%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f'. - '%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f'. - '%20%21%22%23%24%25%26%27()%2a%2b%2c-.%2f'. - '0123456789:%3b%3c%3d%3e%3f'. - '@ABCDEFGHIJKLMNO'. - 'PQRSTUVWXYZ%5b%5c%5d%5e_'. - '%60abcdefghijklmno'. - 'pqrstuvwxyz%7b%7c%7d~%7f', - $newStr); - - self::assertEquals($str, decodePathSegment($newStr)); + $this->assertSame('%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f'. + '%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f'. + '%20%21%22%23%24%25%26%27()%2a%2b%2c-.%2f'. + '0123456789:%3b%3c%3d%3e%3f'. + '@ABCDEFGHIJKLMNO'. + 'PQRSTUVWXYZ%5b%5c%5d%5e_'. + '%60abcdefghijklmno'. + 'pqrstuvwxyz%7b%7c%7d~%7f', $newStr); + + $this->assertSame($str, decodePathSegment($newStr)); } public function testDecode(): void { $str = 'Hello%20Test+Test2.txt'; $newStr = decodePath($str); - self::assertEquals('Hello Test+Test2.txt', $newStr); + $this->assertSame('Hello Test+Test2.txt', $newStr); } #[Depends('testDecode')] @@ -68,7 +64,7 @@ public function testDecodeUmlaut(): void { $str = 'Hello%C3%BC.txt'; $newStr = decodePath($str); - self::assertEquals("Hello\xC3\xBC.txt", $newStr); + $this->assertSame("Hello\xC3\xBC.txt", $newStr); } #[Depends('testDecode')] @@ -84,7 +80,7 @@ public function testDecodeSlavicWords(): void foreach ($words as $word) { $str = rawurlencode($word); $newStr = decodePath($str); - self::assertEquals($word, $newStr); + $this->assertEquals($word, $newStr); } } @@ -93,7 +89,7 @@ public function testDecodeUmlautLatin1(): void { $str = 'Hello%FC.txt'; $newStr = decodePath($str); - self::assertEquals("Hello\xC3\xBC.txt", $newStr); + $this->assertSame("Hello\xC3\xBC.txt", $newStr); } /** @@ -104,6 +100,6 @@ public function testDecodeAccentsWindows7(): void { $str = '/webdav/%C3%A0fo%C3%B3'; $newStr = decodePath($str); - self::assertEquals(strtolower($str), encodePath($newStr)); + $this->assertSame(strtolower($str), encodePath($newStr)); } } diff --git a/tests/www/connection_aborted.php b/tests/www/connection_aborted.php index e9f62abc..ed4aac41 100644 --- a/tests/www/connection_aborted.php +++ b/tests/www/connection_aborted.php @@ -4,7 +4,7 @@ use Sabre\HTTP; -include '../bootstrap.php'; +include __DIR__.'/../bootstrap.php'; class DummyStream { diff --git a/tests/www/large.php b/tests/www/large.php index 65fefb55..babd5f6a 100644 --- a/tests/www/large.php +++ b/tests/www/large.php @@ -1,5 +1,7 @@ Date: Tue, 14 Jul 2026 17:31:22 +0200 Subject: [PATCH 3/4] fix: Ensure rector doesn't change public to protected in the ClientTest Signed-off-by: Carl Schwan --- rector.php | 4 ++++ tests/HTTP/ClientTest.php | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/rector.php b/rector.php index 49f2bc1b..0487e3fd 100644 --- a/rector.php +++ b/rector.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector; use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector; use Rector\Config\RectorConfig; use Rector\PHPUnit\AnnotationsToAttributes\Rector\ClassMethod\DataProviderAnnotationToAttributeRector; @@ -34,4 +35,7 @@ )->withSkip([ AddSeeTestAnnotationRector::class, EncapsedStringsToSprintfRector::class, + MakeInheritedMethodVisibilitySameAsParentRector::class => [ + 'tests/HTTP/ClientTest.php', + ], ]); diff --git a/tests/HTTP/ClientTest.php b/tests/HTTP/ClientTest.php index 2949c3ba..4ddcba22 100644 --- a/tests/HTTP/ClientTest.php +++ b/tests/HTTP/ClientTest.php @@ -508,7 +508,7 @@ class ClientMock extends Client /** * Making this method public. */ - protected function receiveCurlHeader($curlHandle, string $headerLine): int + public function receiveCurlHeader($curlHandle, string $headerLine): int { return parent::receiveCurlHeader($curlHandle, $headerLine); } @@ -516,7 +516,7 @@ protected function receiveCurlHeader($curlHandle, string $headerLine): int /** * Making this method public. */ - protected function createCurlSettingsArray(RequestInterface $request): array + public function createCurlSettingsArray(RequestInterface $request): array { return parent::createCurlSettingsArray($request); } @@ -524,7 +524,7 @@ protected function createCurlSettingsArray(RequestInterface $request): array /** * Making this method public. */ - protected function parseCurlResult(string $response, $curlHandle): array + public function parseCurlResult(string $response, $curlHandle): array { return parent::parseCurlResult($response, $curlHandle); } @@ -532,7 +532,7 @@ protected function parseCurlResult(string $response, $curlHandle): array /** * This method is responsible for performing a single request. */ - protected function doRequest(RequestInterface $request): ResponseInterface + public function doRequest(RequestInterface $request): ResponseInterface { $response = null; $this->emit('doRequest', [$request, &$response]); @@ -553,7 +553,7 @@ protected function doRequest(RequestInterface $request): ResponseInterface * * @param resource $curlHandle */ - protected function curlStuff($curlHandle): array + public function curlStuff($curlHandle): array { $return = null; $this->emit('curlStuff', [&$return]); @@ -574,7 +574,7 @@ protected function curlStuff($curlHandle): array * * @param resource $curlHandle */ - protected function curlExec($curlHandle): string + public function curlExec($curlHandle): string { $return = null; $this->emit('curlExec', [&$return]); From e16bab042c1439b08ebd6af7bcfa273a1c3e9742 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Wed, 15 Jul 2026 10:00:34 +0200 Subject: [PATCH 4/4] fix: phpstan in tests Signed-off-by: Carl Schwan --- phpstan.neon | 4 +++- tests/HTTP/FunctionsTest.php | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 97e6a2a0..7127655d 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -19,5 +19,7 @@ parameters: path: tests/* - message: "#^Left side of || is always false.$#" - count: 23 + count: 18 path: lib/Client.php + + - '#Dynamic call to static method PHPUnit\\Framework\\.*#' diff --git a/tests/HTTP/FunctionsTest.php b/tests/HTTP/FunctionsTest.php index ea3fa325..be032713 100644 --- a/tests/HTTP/FunctionsTest.php +++ b/tests/HTTP/FunctionsTest.php @@ -20,7 +20,7 @@ public function testGetHeaderValuesOnValues2(array $result, array $values1, arra } /** - * @return \Iterator>> + * @return \Iterator>> */ public static function getHeaderValuesDataOnValues2(): \Iterator { @@ -37,11 +37,11 @@ public static function getHeaderValuesDataOnValues2(): \Iterator } /** - * @param string $input + * @param list $input * @param array $output */ #[DataProvider('getHeaderValuesData')] - public function testGetHeaderValues(string|array $input, array $output): void + public function testGetHeaderValues(array $input, array $output): void { $this->assertEquals($output, getHeaderValues($input)); } @@ -74,8 +74,8 @@ public static function getHeaderValuesData(): \Iterator } /** - * @param string $input - * @param array $output + * @param string|list $input + * @param array $output */ #[DataProvider('preferData')] public function testPrefer(string|array $input, array $output): void