From 71c81423af1acef693269aa849436705bd03f0d0 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 7 Feb 2026 21:02:52 +0300 Subject: [PATCH 01/14] Remove PSR --- composer.json | 12 +- src/Transport/CurlTransport.php | 2 - src/Transport/NativeTransport.php | 2 - src/Transport/PsrTransport.php | 137 --------- .../ResourceReader/StreamResourceReader.php | 52 ---- src/Type/Update/Update.php | 11 - .../PsrWebhookResponseFactory.php | 72 ----- tests/Support/RequestException.php | 22 -- .../CurlTransport/CurlTransportTest.php | 54 ---- .../NativeTransport/NativeTransportTest.php | 72 +---- tests/Transport/NativeTransport/test.txt | 1 + .../PsrTransport/DownloadFileTo/.gitignore | 1 - .../PsrTransportDownloadFileToTest.php | 83 ------ .../PsrTransportDownloadFileTest.php | 116 -------- .../PsrTransport/PsrTransportTest.php | 274 ------------------ .../StrictTypeRequest/StrictTypeRequest.php | 57 ---- .../StrictTypeRequestFactory.php | 16 - .../StrictTypeRequestTest.php | 45 --- tests/Type/Update/UpdateTest.php | 24 -- .../PsrWebhookResponseFactoryTest.php | 60 ---- .../StrictTypeResponse/StrictTypeResponse.php | 50 ---- .../StrictTypeResponseFactory.php | 16 - .../StrictTypeResponseTest.php | 37 --- tools/infection/composer.json | 2 +- tools/php-cs-fixer/composer.json | 2 +- tools/psalm/composer.json | 2 +- tools/rector/composer.json | 2 +- 27 files changed, 18 insertions(+), 1206 deletions(-) delete mode 100644 src/Transport/PsrTransport.php delete mode 100644 src/Transport/ResourceReader/StreamResourceReader.php delete mode 100644 src/WebhookResponse/PsrWebhookResponseFactory.php delete mode 100644 tests/Support/RequestException.php create mode 100644 tests/Transport/NativeTransport/test.txt delete mode 100644 tests/Transport/PsrTransport/DownloadFileTo/.gitignore delete mode 100644 tests/Transport/PsrTransport/DownloadFileTo/PsrTransportDownloadFileToTest.php delete mode 100644 tests/Transport/PsrTransport/PsrTransportDownloadFileTest.php delete mode 100644 tests/Transport/PsrTransport/PsrTransportTest.php delete mode 100644 tests/Transport/PsrTransport/StrictTypeRequest/StrictTypeRequest.php delete mode 100644 tests/Transport/PsrTransport/StrictTypeRequest/StrictTypeRequestFactory.php delete mode 100644 tests/Transport/PsrTransport/StrictTypeRequest/StrictTypeRequestTest.php delete mode 100644 tests/WebhookResponse/PsrWebhookResponseFactory/PsrWebhookResponseFactoryTest.php delete mode 100644 tests/WebhookResponse/PsrWebhookResponseFactory/StrictTypeResponse/StrictTypeResponse.php delete mode 100644 tests/WebhookResponse/PsrWebhookResponseFactory/StrictTypeResponse/StrictTypeResponseFactory.php delete mode 100644 tests/WebhookResponse/PsrWebhookResponseFactory/StrictTypeResponse/StrictTypeResponseTest.php diff --git a/composer.json b/composer.json index 2ffafe18..3181d6d3 100644 --- a/composer.json +++ b/composer.json @@ -30,21 +30,17 @@ } ], "require": { - "php-64bit": "8.2 - 8.5", - "php-http/multipart-stream-builder": "^1.4.2", - "psr/http-client": "^1.0", - "psr/http-factory": "^1.1", - "psr/http-message": "^1.1 || ^2.0" + "php-64bit": "8.2 - 8.5" }, "require-dev": { "ext-curl": "*", - "bamarni/composer-bin-plugin": "^1.8.3", + "bamarni/composer-bin-plugin": "^1.9.1", "httpsoft/http-message": "^1.1.6", "php-http/curl-client": "^2.4.0", - "phpunit/phpunit": "^11.5.46", + "phpunit/phpunit": "^11.5.51", "psr/log": "^3.0.2", "yiisoft/files": "^2.1", - "yiisoft/test-support": "^3.1.0" + "yiisoft/test-support": "^3.2.0" }, "suggest": { "ext-curl": "To use `CurlTransport`.", diff --git a/src/Transport/CurlTransport.php b/src/Transport/CurlTransport.php index f121b2d7..f82b29b1 100644 --- a/src/Transport/CurlTransport.php +++ b/src/Transport/CurlTransport.php @@ -11,7 +11,6 @@ use Phptg\BotApi\Curl\CurlInterface; use Phptg\BotApi\Transport\ResourceReader\NativeResourceReader; use Phptg\BotApi\Transport\ResourceReader\ResourceReaderInterface; -use Phptg\BotApi\Transport\ResourceReader\StreamResourceReader; use function is_int; @@ -29,7 +28,6 @@ public function __construct( private array $resourceReaders = [ new NativeResourceReader(), - new StreamResourceReader(), ], private CurlInterface $curl = new Curl(), ) { diff --git a/src/Transport/NativeTransport.php b/src/Transport/NativeTransport.php index ef30443e..3e431a69 100644 --- a/src/Transport/NativeTransport.php +++ b/src/Transport/NativeTransport.php @@ -6,7 +6,6 @@ use Phptg\BotApi\Transport\ResourceReader\NativeResourceReader; use Phptg\BotApi\Transport\ResourceReader\ResourceReaderInterface; -use Phptg\BotApi\Transport\ResourceReader\StreamResourceReader; use RuntimeException; use Phptg\BotApi\Transport\MimeTypeResolver\ApacheMimeTypeResolver; use Phptg\BotApi\Transport\MimeTypeResolver\MimeTypeResolverInterface; @@ -32,7 +31,6 @@ public function __construct( private MimeTypeResolverInterface $mimeTypeResolver = new ApacheMimeTypeResolver(), private array $resourceReaders = [ new NativeResourceReader(), - new StreamResourceReader(), ], ) {} diff --git a/src/Transport/PsrTransport.php b/src/Transport/PsrTransport.php deleted file mode 100644 index 89fb8973..00000000 --- a/src/Transport/PsrTransport.php +++ /dev/null @@ -1,137 +0,0 @@ -send( - $this->requestFactory->createRequest('GET', $url), - ); - } - - public function post(string $url, string $body, array $headers): ApiResponse - { - $request = $this->requestFactory->createRequest('POST', $url); - - $stream = $this->streamFactory->createStream($body); - $request = $request->withBody($stream); - - foreach ($headers as $name => $value) { - $request = $request->withHeader($name, $value); - } - - return $this->send($request); - } - - public function postWithFiles(string $url, array $data, array $files): ApiResponse - { - $streamBuilder = new MultipartStreamBuilder($this->streamFactory); - foreach ($data as $key => $value) { - $streamBuilder->addResource($key, (string) $value); - } - foreach ($files as $key => $file) { - if (!is_resource($file->resource) && !$file->resource instanceof StreamInterface) { - throw new LogicException('File resource must be a valid resource or instance of StreamInterface.'); - } - $streamBuilder->addResource( - $key, - $file->resource, - $file->filename === null ? [] : ['filename' => $file->filename], - ); - } - $body = $streamBuilder->build(); - $contentType = 'multipart/form-data; boundary=' . $streamBuilder->getBoundary() . '; charset=utf-8'; - - $request = $this->requestFactory - ->createRequest('POST', $url) - ->withHeader('Content-Length', (string) $body->getSize()) - ->withHeader('Content-Type', $contentType) - ->withBody($body); - - return $this->send($request); - } - - public function downloadFile(string $url): string - { - return $this->internalDownload($url)->getContents(); - } - - public function downloadFileTo(string $url, string $savePath): void - { - $body = $this->internalDownload($url); - - $content = $body->detach(); - $content ??= $body->getContents(); - - set_error_handler( - static function (int $errorNumber, string $errorString): bool { - throw new SaveFileException($errorString); - }, - ); - try { - file_put_contents($savePath, $content); - } finally { - restore_error_handler(); - } - } - - private function send(RequestInterface $request): ApiResponse - { - $response = $this->client->sendRequest($request); - - $body = $response->getBody(); - if ($body->isSeekable()) { - $body->rewind(); - } - - return new ApiResponse( - $response->getStatusCode(), - $body->getContents(), - ); - } - - /** - * @throws DownloadFileException - */ - private function internalDownload(string $url): StreamInterface - { - $request = $this->requestFactory->createRequest('GET', $url); - - try { - $response = $this->client->sendRequest($request); - } catch (ClientExceptionInterface $exception) { - throw new DownloadFileException($exception->getMessage(), previous: $exception); - } - - $body = $response->getBody(); - if ($body->isSeekable()) { - $body->rewind(); - } - - return $body; - } -} diff --git a/src/Transport/ResourceReader/StreamResourceReader.php b/src/Transport/ResourceReader/StreamResourceReader.php deleted file mode 100644 index fefbea55..00000000 --- a/src/Transport/ResourceReader/StreamResourceReader.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * @api - */ -final class StreamResourceReader implements ResourceReaderInterface -{ - /** - * @param StreamInterface $resource The PSR-7 stream to read from. - * - * @return string The content of the stream. - */ - public function read(mixed $resource): string - { - if ($resource->isSeekable()) { - $resource->rewind(); - } - - return $resource->getContents(); - } - - /** - * @param StreamInterface $resource The PSR-7 stream to get URI from. - * - * @return string The stream URI. - */ - public function getUri(mixed $resource): string - { - /** - * @var string - */ - return $resource->getMetadata('uri'); - } - - public function supports(mixed $resource): bool - { - return $resource instanceof StreamInterface; - } -} diff --git a/src/Type/Update/Update.php b/src/Type/Update/Update.php index cf8aecad..4c649918 100644 --- a/src/Type/Update/Update.php +++ b/src/Type/Update/Update.php @@ -5,7 +5,6 @@ namespace Phptg\BotApi\Type\Update; use JsonException; -use Psr\Http\Message\ServerRequestInterface; use Psr\Log\LoggerInterface; use Phptg\BotApi\LogContextFactory; use Phptg\BotApi\ParseResult\ResultFactory; @@ -107,14 +106,4 @@ public static function fromJson(string $json, ?LoggerInterface $logger = null): $update->rawDecoded = $decodedJson; return $update; } - - /** - * Create a new `Update` object from PSR-7 server request. - * - * @throws TelegramParseResultException - */ - public static function fromServerRequest(ServerRequestInterface $request, ?LoggerInterface $logger = null): Update - { - return self::fromJson((string) $request->getBody(), $logger); - } } diff --git a/src/WebhookResponse/PsrWebhookResponseFactory.php b/src/WebhookResponse/PsrWebhookResponseFactory.php deleted file mode 100644 index 54193d0f..00000000 --- a/src/WebhookResponse/PsrWebhookResponseFactory.php +++ /dev/null @@ -1,72 +0,0 @@ -streamFactory->createStream( - json_encode($webhookResponse->getData(), JSON_THROW_ON_ERROR), - ); - - return $this->responseFactory - ->createResponse() - ->withBody($body) - ->withHeader('Content-Type', 'application/json; charset=utf-8') - ->withHeader('Content-Length', (string) $body->getSize()); - } - - /** - * Creates a PSR-7 HTTP response directly from a method. - * This is a convenience method that creates a {@see WebhookResponse} internally. - * - * @param MethodInterface $method The Telegram Bot API method to be sent as webhook response. - * - * @return ResponseInterface The PSR-7 HTTP response with JSON body and appropriate headers. - * - * @throws MethodNotSupportedException If method doesn't support sending via a webhook response. - */ - public function byMethod(MethodInterface $method): ResponseInterface - { - return $this->create(new WebhookResponse($method)); - } -} diff --git a/tests/Support/RequestException.php b/tests/Support/RequestException.php deleted file mode 100644 index c32f79d1..00000000 --- a/tests/Support/RequestException.php +++ /dev/null @@ -1,22 +0,0 @@ -request; - } -} diff --git a/tests/Transport/CurlTransport/CurlTransportTest.php b/tests/Transport/CurlTransport/CurlTransportTest.php index 02539b65..50fdfadd 100644 --- a/tests/Transport/CurlTransport/CurlTransportTest.php +++ b/tests/Transport/CurlTransport/CurlTransportTest.php @@ -133,60 +133,6 @@ public function testPostWithLocalFiles(): void assertInstanceOf(CurlShareHandle::class, $options[CURLOPT_SHARE]); } - public function testPostWithStreamFile(): void - { - $curl = new CurlMock( - execResult: '{"ok":true,"result":[]}', - getinfoResult: [CURLINFO_HTTP_CODE => 200], - ); - $transport = new CurlTransport(curl: $curl); - - $transport->postWithFiles( - 'sendPhoto', - [], - [ - 'photo1' => new InputFile( - (new StreamFactory())->createStream('test1'), - ), - 'photo2' => new InputFile( - (new StreamFactory())->createStream('test2'), - 'test.jpg', - ), - ], - ); - - assertEquals( - [ - 'photo1' => new CURLStringFile('test1', ''), - 'photo2' => new CURLStringFile('test2', 'test.jpg'), - ], - $curl->getOptions()[CURLOPT_POSTFIELDS] ?? null, - ); - } - - public function testSeekableStream(): void - { - $curl = new CurlMock(); - $transport = new CurlTransport(curl: $curl); - - $stream = (new StreamFactory())->createStream('test1'); - $stream->getContents(); - $transport->postWithFiles( - 'sendPhoto', - [], - [ - 'photo' => new InputFile($stream), - ], - ); - - assertEquals( - [ - 'photo' => new CURLStringFile('test1', ''), - ], - $curl->getOptions()[CURLOPT_POSTFIELDS] ?? null, - ); - } - public function testSeekableResource(): void { $curl = new CurlMock(); diff --git a/tests/Transport/NativeTransport/NativeTransportTest.php b/tests/Transport/NativeTransport/NativeTransportTest.php index e5ab02b8..fabce3ce 100644 --- a/tests/Transport/NativeTransport/NativeTransportTest.php +++ b/tests/Transport/NativeTransport/NativeTransportTest.php @@ -146,59 +146,6 @@ public function testPostWithLocalFiles(): void assertTrue($request['options']['http']['ignore_errors']); } - public function testPostWithStreamFile(): void - { - $transport = new NativeTransport(); - - StreamMock::enable( - responseHeaders: [ - 'HTTP/1.1 200 OK', - 'Content-Type: text/json', - ], - responseBody: '{"ok":true,"result":[]}', - ); - - $response = $transport->postWithFiles( - 'http://url/sendPhoto', - [], - [ - 'file1' => new InputFile( - (new StreamFactory())->createStream('test1'), - ), - 'file2' => new InputFile( - (new StreamFactory())->createStream('test2'), - 'test.txt', - ), - ], - ); - - $request = StreamMock::disable(); - - assertSame(200, $response->statusCode); - assertSame('{"ok":true,"result":[]}', $response->body); - assertSame('http://url/sendPhoto', $request['path']); - assertSame(['http'], array_keys($request['options'])); - assertSame(['method', 'header', 'content', 'ignore_errors'], array_keys($request['options']['http'])); - assertSame('POST', $request['options']['http']['method']); - assertStringStartsWith('Content-type: multipart/form-data; boundary=', $request['options']['http']['header']); - assertStringEndsWith('; charset=utf-8', $request['options']['http']['header']); - assertStringContainsString('test2', $request['options']['http']['content']); - assertStringContainsString( - "Content-Disposition: form-data; name=\"file1\"\r\n" - . "\r\n" - . "test1\r\n", - $request['options']['http']['content'], - ); - assertStringContainsString( - "Content-Disposition: form-data; name=\"file2\"; filename=\"test.txt\"\r\n" - . "Content-Type: text/plain\r\n" - . "\r\n" - . "test2\r\n", - $request['options']['http']['content'], - ); - assertTrue($request['options']['http']['ignore_errors']); - } - public function testPostWithFiles(): void { $transport = new NativeTransport(); @@ -217,9 +164,7 @@ public function testPostWithFiles(): void 'ages' => [23, 45], ], [ - 'file1' => new InputFile( - (new StreamFactory())->createStream('test1'), - ), + 'file1' => InputFile::fromLocalFile(__DIR__ . '/test.txt'), ], ); @@ -233,9 +178,11 @@ public function testPostWithFiles(): void $request['options']['http']['content'], ); assertStringContainsString( - "Content-Disposition: form-data; name=\"file1\"\r\n" + "Content-Disposition: form-data; name=\"file1\"; filename=\"test.txt\"\r\n" + . "Content-Type: text/plain\r\n" . "\r\n" - . "test1\r\n", + . "hello\n" + . "\r\n", $request['options']['http']['content'], ); } @@ -263,9 +210,7 @@ public function resolve(InputFileData $fileData): ?string 'http://url/method', [], [ - 'file1' => new InputFile( - (new StreamFactory())->createStream('test1'), - ), + 'file1' => InputFile::fromLocalFile(__DIR__ . '/test.txt'), ], ); @@ -273,10 +218,11 @@ public function resolve(InputFileData $fileData): ?string assertTrue(isset($request['options']['http']['content'])); assertStringContainsString( - "Content-Disposition: form-data; name=\"file1\"\r\n" + "Content-Disposition: form-data; name=\"file1\"; filename=\"test.txt\"\r\n" . "Content-Type: text/custom\r\n" . "\r\n" - . "test1\r\n", + . "hello\n" + . "\r\n", $request['options']['http']['content'], ); } diff --git a/tests/Transport/NativeTransport/test.txt b/tests/Transport/NativeTransport/test.txt new file mode 100644 index 00000000..ce013625 --- /dev/null +++ b/tests/Transport/NativeTransport/test.txt @@ -0,0 +1 @@ +hello diff --git a/tests/Transport/PsrTransport/DownloadFileTo/.gitignore b/tests/Transport/PsrTransport/DownloadFileTo/.gitignore deleted file mode 100644 index f78da738..00000000 --- a/tests/Transport/PsrTransport/DownloadFileTo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/runtime diff --git a/tests/Transport/PsrTransport/DownloadFileTo/PsrTransportDownloadFileToTest.php b/tests/Transport/PsrTransport/DownloadFileTo/PsrTransportDownloadFileToTest.php deleted file mode 100644 index 64f52686..00000000 --- a/tests/Transport/PsrTransport/DownloadFileTo/PsrTransportDownloadFileToTest.php +++ /dev/null @@ -1,83 +0,0 @@ -createMock(ClientInterface::class); - $client - ->expects($this->once()) - ->method('sendRequest') - ->with($httpRequest) - ->willReturn(new Response(200, body: $streamFactory->createStream('hello-content'))); - - $requestFactory = $this->createMock(RequestFactoryInterface::class); - $requestFactory - ->expects($this->once()) - ->method('createRequest') - ->with('GET', 'https://example.com/test.txt') - ->willReturn($httpRequest); - - $transport = new PsrTransport( - $client, - $requestFactory, - $streamFactory, - ); - - $filePath = self::RUNTIME_PATH . '/file.txt'; - - $transport->downloadFileTo('https://example.com/test.txt', $filePath); - - assertFileExists($filePath); - assertStringEqualsFile($filePath, 'hello-content'); - } - - public function testExceptionOnFilePutContents(): void - { - $filePath = self::RUNTIME_PATH . '/exception-file-put-contents.txt'; - touch($filePath); - chmod($filePath, 0444); - assertFileExists($filePath); - - $client = $this->createMock(ClientInterface::class); - $client->method('sendRequest')->willReturn(new Response(200)); - - $transport = new PsrTransport( - $client, - $this->createMock(RequestFactoryInterface::class), - new StreamFactory(), - ); - - $this->expectException(SaveFileException::class); - $this->expectExceptionMessage('Failed to open stream: Permission denied'); - $transport->downloadFileTo('https://example.com/test.txt', $filePath); - } -} diff --git a/tests/Transport/PsrTransport/PsrTransportDownloadFileTest.php b/tests/Transport/PsrTransport/PsrTransportDownloadFileTest.php deleted file mode 100644 index 0f875b2a..00000000 --- a/tests/Transport/PsrTransport/PsrTransportDownloadFileTest.php +++ /dev/null @@ -1,116 +0,0 @@ -createMock(ClientInterface::class); - $client - ->expects($this->once()) - ->method('sendRequest') - ->with($httpRequest) - ->willReturn(new Response(200, body: $streamFactory->createStream('hello-content'))); - - $requestFactory = $this->createMock(RequestFactoryInterface::class); - $requestFactory - ->expects($this->once()) - ->method('createRequest') - ->with('GET', 'https://example.com/test.txt') - ->willReturn($httpRequest); - - $transport = new PsrTransport( - $client, - $requestFactory, - $streamFactory, - ); - - $result = $transport->downloadFile('https://example.com/test.txt'); - - assertSame('hello-content', $result); - } - - public function testSendRequestException(): void - { - $httpRequest = new Request(); - $requestException = new RequestException('test', $httpRequest); - - $client = $this->createMock(ClientInterface::class); - $client - ->method('sendRequest') - ->with($httpRequest) - ->willThrowException($requestException); - - $requestFactory = $this->createMock(RequestFactoryInterface::class); - $requestFactory->method('createRequest')->willReturn($httpRequest); - - $transport = new PsrTransport( - $client, - $requestFactory, - new StreamFactory(), - ); - - $exception = null; - try { - $transport->downloadFile('https://example.com/test.txt'); - } catch (Throwable $exception) { - } - - assertInstanceOf(DownloadFileException::class, $exception); - assertSame('test', $exception->getMessage()); - assertSame($requestException, $exception->getPrevious()); - } - - public function testRewind(): void - { - $streamFactory = new StreamFactory(); - $httpRequest = new Request(); - - $httpResponse = new Response(200, body: $streamFactory->createStream('hello-content')); - $httpResponse->getBody()->getContents(); - - $client = $this->createMock(ClientInterface::class); - $client - ->expects($this->once()) - ->method('sendRequest') - ->with($httpRequest) - ->willReturn($httpResponse); - - $requestFactory = $this->createMock(RequestFactoryInterface::class); - $requestFactory - ->expects($this->once()) - ->method('createRequest') - ->with('GET', 'https://example.com/test.txt') - ->willReturn($httpRequest); - - $transport = new PsrTransport( - $client, - $requestFactory, - $streamFactory, - ); - - $result = $transport->downloadFile('https://example.com/test.txt'); - - assertSame('hello-content', $result); - } -} diff --git a/tests/Transport/PsrTransport/PsrTransportTest.php b/tests/Transport/PsrTransport/PsrTransportTest.php deleted file mode 100644 index 1aacf5d7..00000000 --- a/tests/Transport/PsrTransport/PsrTransportTest.php +++ /dev/null @@ -1,274 +0,0 @@ -createMock(ClientInterface::class); - $client - ->expects($this->once()) - ->method('sendRequest') - ->with($httpRequest) - ->willReturn(new Response(201)); - - $requestFactory = $this->createMock(RequestFactoryInterface::class); - $requestFactory - ->expects($this->once()) - ->method('createRequest') - ->with('GET', '//url/getMe?key=value&array=%5B1%2C%22test%22%5D') - ->willReturn($httpRequest); - - $transport = new PsrTransport( - $client, - $requestFactory, - new StreamFactory(), - ); - - $response = $transport->get('//url/getMe?key=value&array=%5B1%2C%22test%22%5D'); - - assertSame(201, $response->statusCode); - } - - public function testPost(): void - { - $httpRequest = new Request(); - - $client = $this->createMock(ClientInterface::class); - $client - ->expects($this->once()) - ->method('sendRequest') - ->with( - new Callback(function ($request): bool { - assertInstanceOf(Request::class, $request); - assertSame( - [ - 'Content-Length' => ['0'], - 'Content-Type' => ['application/json; charset=utf-8'], - ], - $request->getHeaders(), - ); - assertSame('', $request->getBody()->getContents()); - return true; - }), - ) - ->willReturn(new Response(201)); - - $requestFactory = $this->createMock(RequestFactoryInterface::class); - $requestFactory - ->expects($this->once()) - ->method('createRequest') - ->with('POST', '//url/logOut') - ->willReturn($httpRequest); - - $transport = new PsrTransport( - $client, - $requestFactory, - new StreamFactory(), - ); - - $response = $transport->post( - '//url/logOut', - '', - [ - 'Content-Length' => '0', - 'Content-Type' => 'application/json; charset=utf-8', - ], - ); - - assertSame(201, $response->statusCode); - } - - public function testPostWithData(): void - { - $httpRequest = new Request(); - - $client = $this->createMock(ClientInterface::class); - $client - ->expects($this->once()) - ->method('sendRequest') - ->with( - new Callback(function ($request): bool { - assertInstanceOf(Request::class, $request); - assertSame( - [ - 'Content-Length' => ['29'], - 'Content-Type' => ['application/json; charset=utf-8'], - ], - $request->getHeaders(), - ); - assertSame('{"chat_id":123,"text":"test"}', $request->getBody()->getContents()); - return true; - }), - ) - ->willReturn(new Response(201)); - - $requestFactory = $this->createMock(RequestFactoryInterface::class); - $requestFactory - ->expects($this->once()) - ->method('createRequest') - ->with('POST', '//url/sendMessage') - ->willReturn($httpRequest); - - $transport = new PsrTransport( - $client, - $requestFactory, - new StreamFactory(), - ); - - $response = $transport->post( - '//url/sendMessage', - '{"chat_id":123,"text":"test"}', - [ - 'Content-Length' => '29', - 'Content-Type' => 'application/json; charset=utf-8', - ], - ); - - assertSame(201, $response->statusCode); - } - - public function testPostWithFiles(): void - { - $httpRequest = new Request(); - - $client = $this->createMock(ClientInterface::class); - $client - ->expects($this->once()) - ->method('sendRequest') - ->with( - new Callback(function ($request): bool { - assertInstanceOf(Request::class, $request); - /** @var Request $request */ - $requestHeaders = $request->getHeaders(); - assertSame(['Content-Length', 'Content-Type'], array_keys($requestHeaders)); - assertSame($requestHeaders['Content-Length'], ['332']); - assertSame([0], array_keys($requestHeaders['Content-Type'])); - assertSame( - 1, - preg_match( - '~multipart/form-data; boundary=([\da-f]+.[\da-f]+); charset=utf-8~', - $requestHeaders['Content-Type'][0], - $matches, - ), - ); - assertStringContainsStringIgnoringLineEndings( - <<getBody()->getContents(), - ); - return true; - }), - ) - ->willReturn(new Response(201)); - - $requestFactory = $this->createMock(RequestFactoryInterface::class); - $requestFactory - ->expects($this->once()) - ->method('createRequest') - ->with('POST', '//url/sendPhoto') - ->willReturn($httpRequest); - - $transport = new PsrTransport( - $client, - $requestFactory, - new StreamFactory(), - ); - - $response = $transport->postWithFiles( - '//url/sendPhoto', - [ - 'chat_id' => 123, - 'caption' => 'hello', - ], - [ - 'photo' => new InputFile( - (new StreamFactory())->createStream('test-file-body'), - 'face.png', - ), - ], - ); - - assertSame(201, $response->statusCode); - } - - public function testRewind(): void - { - $streamFactory = new StreamFactory(); - - $httpResponse = new Response(201, body: $streamFactory->createStream('hello')); - $httpResponse->getBody()->getContents(); - - $client = $this->createMock(ClientInterface::class); - $client->method('sendRequest')->willReturn($httpResponse); - - $httpRequestFactory = $this->createMock(RequestFactoryInterface::class); - - $transport = new PsrTransport( - $client, - $httpRequestFactory, - $streamFactory, - ); - - $response = $transport->get('getMe'); - - assertSame(201, $response->statusCode); - assertSame('hello', $response->body); - } - - public function testPostWithFilesThrowsExceptionForInvalidResource(): void - { - $client = $this->createMock(ClientInterface::class); - $requestFactory = $this->createMock(RequestFactoryInterface::class); - $file = new InputFile('invalid-resource'); - - $transport = new PsrTransport( - $client, - $requestFactory, - new StreamFactory(), - ); - - $this->expectException(LogicException::class); - $this->expectExceptionMessage('File resource must be a valid resource or instance of StreamInterface.'); - - $transport->postWithFiles( - '//url/sendPhoto', - ['chat_id' => 123], - ['photo' => $file], - ); - } -} diff --git a/tests/Transport/PsrTransport/StrictTypeRequest/StrictTypeRequest.php b/tests/Transport/PsrTransport/StrictTypeRequest/StrictTypeRequest.php deleted file mode 100644 index 1e68ef6f..00000000 --- a/tests/Transport/PsrTransport/StrictTypeRequest/StrictTypeRequest.php +++ /dev/null @@ -1,57 +0,0 @@ -init($method, $uri, $headers, $body, $protocol); - } - - public function withHeader(string $name, $value): MessageInterface - { - $this->checkValue($value); - return $this->traitWithHeader($name, $value); - } - - private function checkValue($value): void - { - if (is_array($value)) { - foreach ($value as $item) { - if (!is_string($item)) { - throw new LogicException('Invalid value.'); - } - } - return; - } - if (is_string($value)) { - return; - } - throw new LogicException('Invalid value.'); - } -} diff --git a/tests/Transport/PsrTransport/StrictTypeRequest/StrictTypeRequestFactory.php b/tests/Transport/PsrTransport/StrictTypeRequest/StrictTypeRequestFactory.php deleted file mode 100644 index 6d07d494..00000000 --- a/tests/Transport/PsrTransport/StrictTypeRequest/StrictTypeRequestFactory.php +++ /dev/null @@ -1,16 +0,0 @@ -createStream('hello')); - - $client = $this->createMock(ClientInterface::class); - $client->method('sendRequest')->willReturn($httpResponse); - - $transport = new PsrTransport( - $client, - new StrictTypeRequestFactory(), - $streamFactory, - ); - - $file = new InputFile( - $streamFactory->createStream('file content'), - ); - $response = $transport->postWithFiles( - 'https://api.example.com/test', - ['key1' => 'value1'], - ['file1' => $file], - ); - - assertSame(201, $response->statusCode); - assertSame('hello', $response->body); - } -} diff --git a/tests/Type/Update/UpdateTest.php b/tests/Type/Update/UpdateTest.php index 80c08499..7da1d705 100644 --- a/tests/Type/Update/UpdateTest.php +++ b/tests/Type/Update/UpdateTest.php @@ -381,30 +381,6 @@ public function testFromJsonString(): void Update::fromJson('asdf{'); } - public function testFromServerRequest(): void - { - $request = $this->createMock(ServerRequestInterface::class); - $request->method('getBody')->willReturn( - new class implements StreamInterface { - use StreamTrait; - - public function __toString(): string - { - return '{"update_id":33990940}'; - } - }, - ); - - $update = Update::fromServerRequest($request); - assertSame(33990940, $update->updateId); - assertSame('{"update_id":33990940}', $update->getRaw()); - assertSame(['update_id' => 33990940], $update->getRaw(true)); - - $this->expectException(TelegramParseResultException::class); - $this->expectExceptionMessage('Failed to decode JSON.'); - Update::fromJson('asdf{'); - } - public function testFromJsonDecodeError(): void { $logger = new SimpleLogger(); diff --git a/tests/WebhookResponse/PsrWebhookResponseFactory/PsrWebhookResponseFactoryTest.php b/tests/WebhookResponse/PsrWebhookResponseFactory/PsrWebhookResponseFactoryTest.php deleted file mode 100644 index ecef02f9..00000000 --- a/tests/WebhookResponse/PsrWebhookResponseFactory/PsrWebhookResponseFactoryTest.php +++ /dev/null @@ -1,60 +0,0 @@ -createFactory(); - $method = new SendMessage(chatId: 'x1', text: 'Hello'); - $webhookResponse = new WebhookResponse($method); - - $response = $factory->create($webhookResponse); - - assertSame( - [ - 'Content-Type' => ['application/json; charset=utf-8'], - 'Content-Length' => ['54'], - ], - $response->getHeaders(), - ); - assertSame('{"method":"sendMessage","chat_id":"x1","text":"Hello"}', $response->getBody()->getContents()); - } - - public function testByMethod(): void - { - $factory = $this->createFactory(); - $method = new SendMessage(chatId: 'x1', text: 'Hello'); - - $response = $factory->byMethod($method); - - assertSame( - [ - 'Content-Type' => ['application/json; charset=utf-8'], - 'Content-Length' => ['54'], - ], - $response->getHeaders(), - ); - assertSame('{"method":"sendMessage","chat_id":"x1","text":"Hello"}', $response->getBody()->getContents()); - } - - private function createFactory(): PsrWebhookResponseFactory - { - return new PsrWebhookResponseFactory( - new ResponseFactory(), - new StreamFactory(), - ); - } -} diff --git a/tests/WebhookResponse/PsrWebhookResponseFactory/StrictTypeResponse/StrictTypeResponse.php b/tests/WebhookResponse/PsrWebhookResponseFactory/StrictTypeResponse/StrictTypeResponse.php deleted file mode 100644 index f63a27da..00000000 --- a/tests/WebhookResponse/PsrWebhookResponseFactory/StrictTypeResponse/StrictTypeResponse.php +++ /dev/null @@ -1,50 +0,0 @@ -init($statusCode, $reasonPhrase, $headers, $body, $protocol); - } - - public function withHeader(string $name, $value): MessageInterface - { - $this->checkValue($value); - return $this->traitWithHeader($name, $value); - } - - private function checkValue($value): void - { - if (is_string($value)) { - return; - } - - throw new LogicException( - 'Invalid header value: expected string, got ' . get_debug_type($value), - ); - } -} diff --git a/tests/WebhookResponse/PsrWebhookResponseFactory/StrictTypeResponse/StrictTypeResponseFactory.php b/tests/WebhookResponse/PsrWebhookResponseFactory/StrictTypeResponse/StrictTypeResponseFactory.php deleted file mode 100644 index a37b5510..00000000 --- a/tests/WebhookResponse/PsrWebhookResponseFactory/StrictTypeResponse/StrictTypeResponseFactory.php +++ /dev/null @@ -1,16 +0,0 @@ -create($webhookResponse); - - assertSame( - [ - 'Content-Type' => ['application/json; charset=utf-8'], - 'Content-Length' => ['54'], - ], - $response->getHeaders(), - ); - assertSame('{"method":"sendMessage","chat_id":"x1","text":"Hello"}', $response->getBody()->getContents()); - } -} diff --git a/tools/infection/composer.json b/tools/infection/composer.json index d4043eaf..571c7809 100644 --- a/tools/infection/composer.json +++ b/tools/infection/composer.json @@ -1,6 +1,6 @@ { "require-dev": { - "infection/infection": "^0.32" + "infection/infection": "^0.32.3" }, "config": { "allow-plugins": { diff --git a/tools/php-cs-fixer/composer.json b/tools/php-cs-fixer/composer.json index 15807727..24514552 100644 --- a/tools/php-cs-fixer/composer.json +++ b/tools/php-cs-fixer/composer.json @@ -1,5 +1,5 @@ { "require-dev": { - "friendsofphp/php-cs-fixer": "^3.92.3" + "friendsofphp/php-cs-fixer": "^3.93.1" } } diff --git a/tools/psalm/composer.json b/tools/psalm/composer.json index 6f68d799..83afe137 100644 --- a/tools/psalm/composer.json +++ b/tools/psalm/composer.json @@ -1,5 +1,5 @@ { "require-dev": { - "vimeo/psalm": "^6.14.3" + "vimeo/psalm": "^6.15.0" } } diff --git a/tools/rector/composer.json b/tools/rector/composer.json index b8ad905a..bed00e8b 100644 --- a/tools/rector/composer.json +++ b/tools/rector/composer.json @@ -1,5 +1,5 @@ { "require-dev": { - "rector/rector": "^2.3.0" + "rector/rector": "^2.3.6" } } From dbdca8e522234faa748f71203a11c12a2a0942d2 Mon Sep 17 00:00:00 2001 From: vjik <525501+vjik@users.noreply.github.com> Date: Sat, 7 Feb 2026 18:05:12 +0000 Subject: [PATCH 02/14] Apply PHP CS Fixer and Rector changes (CI) --- tests/Transport/CurlTransport/CurlTransportTest.php | 1 - tests/Transport/NativeTransport/NativeTransportTest.php | 3 --- tests/Type/Update/UpdateTest.php | 3 --- 3 files changed, 7 deletions(-) diff --git a/tests/Transport/CurlTransport/CurlTransportTest.php b/tests/Transport/CurlTransport/CurlTransportTest.php index 50fdfadd..0d7b6873 100644 --- a/tests/Transport/CurlTransport/CurlTransportTest.php +++ b/tests/Transport/CurlTransport/CurlTransportTest.php @@ -6,7 +6,6 @@ use CurlShareHandle; use CURLStringFile; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use RuntimeException; use Throwable; diff --git a/tests/Transport/NativeTransport/NativeTransportTest.php b/tests/Transport/NativeTransport/NativeTransportTest.php index fabce3ce..5358ddd1 100644 --- a/tests/Transport/NativeTransport/NativeTransportTest.php +++ b/tests/Transport/NativeTransport/NativeTransportTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Transport\NativeTransport; -use HttpSoft\Message\StreamFactory; use Phptg\BotApi\Transport\InputFileData; use PHPUnit\Framework\TestCase; use RuntimeException; @@ -16,8 +15,6 @@ use function PHPUnit\Framework\assertMatchesRegularExpression; use function PHPUnit\Framework\assertSame; use function PHPUnit\Framework\assertStringContainsString; -use function PHPUnit\Framework\assertStringEndsWith; -use function PHPUnit\Framework\assertStringStartsWith; use function PHPUnit\Framework\assertTrue; final class NativeTransportTest extends TestCase diff --git a/tests/Type/Update/UpdateTest.php b/tests/Type/Update/UpdateTest.php index 7da1d705..9d887696 100644 --- a/tests/Type/Update/UpdateTest.php +++ b/tests/Type/Update/UpdateTest.php @@ -4,11 +4,8 @@ namespace Phptg\BotApi\Tests\Type\Update; -use HttpSoft\Message\StreamTrait; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; -use Psr\Http\Message\ServerRequestInterface; -use Psr\Http\Message\StreamInterface; use Throwable; use Phptg\BotApi\ParseResult\TelegramParseResultException; use Phptg\BotApi\ParseResult\ObjectFactory; From caf8ef8138491419258a27c922add793e689e01c Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 7 Feb 2026 21:20:00 +0300 Subject: [PATCH 03/14] remove `httpsoft/http-message` --- composer.json | 1 - tests/CustomMethodTest.php | 3 +-- tests/InputFileCollectorTest.php | 9 ++++----- tests/Method/EditStoryTest.php | 7 +++---- tests/Method/PostStoryTest.php | 7 +++---- tests/Method/SendAnimationTest.php | 5 ++--- tests/Method/SendAudioTest.php | 5 ++--- tests/Method/SendDocumentTest.php | 5 ++--- tests/Method/SendMediaGroupTest.php | 3 +-- tests/Method/SendPaidMediaTest.php | 3 +-- tests/Method/SendPhotoTest.php | 3 +-- tests/Method/SendVideoNoteTest.php | 5 ++--- tests/Method/SendVideoTest.php | 5 ++--- tests/Method/SendVoiceTest.php | 3 +-- .../Method/SetBusinessAccountProfilePhotoTest.php | 7 +++---- tests/Method/Sticker/AddStickerToSetTest.php | 3 +-- tests/Method/Sticker/ReplaceStickerInSetTest.php | 3 +-- tests/Method/Sticker/SendStickerTest.php | 3 +-- .../Method/Sticker/SetStickerSetThumbnailTest.php | 3 +-- tests/Method/Sticker/UploadStickerFileTest.php | 5 ++--- .../UpdatingMessage/EditMessageMediaTest.php | 3 +-- tests/TelegramBotApiTest.php | 15 ++++++--------- .../Transport/CurlTransport/CurlTransportTest.php | 1 - .../NativeTransport/NativeTransportTest.php | 3 --- tests/Type/InputFileTest.php | 11 ++++------- tests/Type/InputMediaAnimationTest.php | 5 ++--- tests/Type/InputMediaAudioTest.php | 5 ++--- tests/Type/InputMediaDocumentTest.php | 5 ++--- tests/Type/InputMediaPhotoTest.php | 3 +-- tests/Type/InputMediaVideoTest.php | 7 +++---- tests/Type/InputPaidMediaPhotoTest.php | 3 +-- tests/Type/InputPaidMediaVideoTest.php | 7 +++---- tests/Type/InputProfilePhotoAnimatedTest.php | 5 ++--- tests/Type/InputProfilePhotoStaticTest.php | 3 +-- tests/Type/InputStoryContentPhotoTest.php | 3 +-- tests/Type/InputStoryContentVideoTest.php | 5 ++--- tests/Type/Sticker/InputStickerTest.php | 3 +-- tests/Type/Update/UpdateTest.php | 3 --- tests/WebhookResponse/WebhookResponseTest.php | 3 +-- 39 files changed, 67 insertions(+), 114 deletions(-) diff --git a/composer.json b/composer.json index 3181d6d3..84a9a216 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,6 @@ "require-dev": { "ext-curl": "*", "bamarni/composer-bin-plugin": "^1.9.1", - "httpsoft/http-message": "^1.1.6", "php-http/curl-client": "^2.4.0", "phpunit/phpunit": "^11.5.51", "psr/log": "^3.0.2", diff --git a/tests/CustomMethodTest.php b/tests/CustomMethodTest.php index aaf157bd..0da77d3e 100644 --- a/tests/CustomMethodTest.php +++ b/tests/CustomMethodTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\ParseResult\ValueProcessor\IntegerValue; use Phptg\BotApi\Transport\HttpMethod; @@ -18,7 +17,7 @@ final class CustomMethodTest extends TestCase { public function testBase(): void { - $photo = new InputFile((new StreamFactory())->createStream('test')); + $photo = new InputFile(null); $method = new CustomMethod( 'getMe', ['param1' => 'value1', 'photo' => $photo], diff --git a/tests/InputFileCollectorTest.php b/tests/InputFileCollectorTest.php index b7e17c25..ca40dc26 100644 --- a/tests/InputFileCollectorTest.php +++ b/tests/InputFileCollectorTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -15,8 +14,8 @@ final class InputFileCollectorTest extends TestCase { public function testBase(): void { - $file1 = new InputFile((new StreamFactory())->createStream()); - $file2 = new InputFile((new StreamFactory())->createStream()); + $file1 = new InputFile(null); + $file2 = new InputFile(null); $collector = new FileCollector(); $collector->add($file1); @@ -32,8 +31,8 @@ public function testBase(): void } public function testCustomParameters(): void { - $file1 = new InputFile((new StreamFactory())->createStream()); - $file2 = new InputFile((new StreamFactory())->createStream()); + $file1 = new InputFile(null); + $file2 = new InputFile(null); $collector = new FileCollector('test', 23); $collector->add($file1); diff --git a/tests/Method/EditStoryTest.php b/tests/Method/EditStoryTest.php index 9d63f344..0527bff6 100644 --- a/tests/Method/EditStoryTest.php +++ b/tests/Method/EditStoryTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Method\EditStory; @@ -25,7 +24,7 @@ final class EditStoryTest extends TestCase { public function testBase(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $content = new InputStoryContentPhoto($file); $method = new EditStory('bcid1', 123, $content); @@ -44,7 +43,7 @@ public function testBase(): void public function testFull(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $content = new InputStoryContentPhoto($file); $captionEntities = [new MessageEntity('bold', 0, 4)]; $storyArea = new StoryArea( @@ -88,7 +87,7 @@ public function testPrepareResult(): void $method = new EditStory( 'bcid1', 123, - new InputStoryContentPhoto(new InputFile((new StreamFactory())->createStream())), + new InputStoryContentPhoto(new InputFile(null)), ); $result = TestHelper::createSuccessStubApi([ diff --git a/tests/Method/PostStoryTest.php b/tests/Method/PostStoryTest.php index 5fa3eb15..c20a2023 100644 --- a/tests/Method/PostStoryTest.php +++ b/tests/Method/PostStoryTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Method\PostStory; @@ -25,7 +24,7 @@ final class PostStoryTest extends TestCase { public function testBase(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $content = new InputStoryContentPhoto($file); $method = new PostStory('bcid1', $content, 86400); @@ -44,7 +43,7 @@ public function testBase(): void public function testFull(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $content = new InputStoryContentPhoto($file); $captionEntities = [new MessageEntity('bold', 0, 4)]; $storyArea = new StoryArea( @@ -91,7 +90,7 @@ public function testPrepareResult(): void { $method = new PostStory( 'bcid1', - new InputStoryContentPhoto(new InputFile((new StreamFactory())->createStream())), + new InputStoryContentPhoto(new InputFile(null)), 86400, ); diff --git a/tests/Method/SendAnimationTest.php b/tests/Method/SendAnimationTest.php index 72d3c020..b80af9ca 100644 --- a/tests/Method/SendAnimationTest.php +++ b/tests/Method/SendAnimationTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\SendAnimation; use Phptg\BotApi\Transport\HttpMethod; @@ -37,8 +36,8 @@ public function testBase(): void public function testFull(): void { - $animation = new InputFile((new StreamFactory())->createStream('test'), 'test.gif'); - $thumbnail = new InputFile((new StreamFactory())->createStream('test'), 'test.jpg'); + $animation = new InputFile(null, 'test.gif'); + $thumbnail = new InputFile(null, 'test.jpg'); $entity = new MessageEntity('bold', 0, 5); $replyParameters = new ReplyParameters(23); $replyMarkup = new ForceReply(); diff --git a/tests/Method/SendAudioTest.php b/tests/Method/SendAudioTest.php index b471bc7d..76d86465 100644 --- a/tests/Method/SendAudioTest.php +++ b/tests/Method/SendAudioTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\SendAudio; use Phptg\BotApi\Transport\HttpMethod; @@ -37,8 +36,8 @@ public function testBase(): void public function testFull(): void { - $audio = new InputFile((new StreamFactory())->createStream('test'), 'test.mp3'); - $thumbnail = new InputFile((new StreamFactory())->createStream('test'), 'test.jpg'); + $audio = new InputFile(null, 'test.mp3'); + $thumbnail = new InputFile(null, 'test.jpg'); $entity = new MessageEntity('bold', 0, 5); $replyParameters = new ReplyParameters(23); $replyMarkup = new ForceReply(); diff --git a/tests/Method/SendDocumentTest.php b/tests/Method/SendDocumentTest.php index eb038590..18a74a87 100644 --- a/tests/Method/SendDocumentTest.php +++ b/tests/Method/SendDocumentTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\SendDocument; use Phptg\BotApi\Transport\HttpMethod; @@ -37,8 +36,8 @@ public function testBase(): void public function testFull(): void { - $document = new InputFile((new StreamFactory())->createStream('test'), 'test.doc'); - $thumbnail = new InputFile((new StreamFactory())->createStream('test'), 'test.jpg'); + $document = new InputFile(null, 'test.doc'); + $thumbnail = new InputFile(null, 'test.jpg'); $entity = new MessageEntity('bold', 0, 5); $replyParameters = new ReplyParameters(23); $replyMarkup = new ForceReply(); diff --git a/tests/Method/SendMediaGroupTest.php b/tests/Method/SendMediaGroupTest.php index 74afdaaa..430ed2f2 100644 --- a/tests/Method/SendMediaGroupTest.php +++ b/tests/Method/SendMediaGroupTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\SendMediaGroup; use Phptg\BotApi\Transport\HttpMethod; @@ -39,7 +38,7 @@ public function testBase(): void public function testFull(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $inputMedia = new InputMediaPhoto($file); $replyParameters = new ReplyParameters(23); $method = new SendMediaGroup( diff --git a/tests/Method/SendPaidMediaTest.php b/tests/Method/SendPaidMediaTest.php index f5286a8b..7c07a598 100644 --- a/tests/Method/SendPaidMediaTest.php +++ b/tests/Method/SendPaidMediaTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\SendPaidMedia; use Phptg\BotApi\Transport\HttpMethod; @@ -40,7 +39,7 @@ public function testBase(): void public function testFull(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $inputMedia = new InputPaidMediaPhoto($file); $entity = new MessageEntity('bold', 0, 4); $replyParameters = new ReplyParameters(23); diff --git a/tests/Method/SendPhotoTest.php b/tests/Method/SendPhotoTest.php index 8b8e1d0f..5b9ffb3d 100644 --- a/tests/Method/SendPhotoTest.php +++ b/tests/Method/SendPhotoTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\SendPhoto; use Phptg\BotApi\Transport\HttpMethod; @@ -37,7 +36,7 @@ public function testBase(): void public function testFull(): void { - $photo = new InputFile((new StreamFactory())->createStream('test'), 'test.png'); + $photo = new InputFile(null, 'test.png'); $entity = new MessageEntity('bold', 0, 5); $replyParameters = new ReplyParameters(23); $replyMarkup = new ForceReply(); diff --git a/tests/Method/SendVideoNoteTest.php b/tests/Method/SendVideoNoteTest.php index 59890d3c..af421b30 100644 --- a/tests/Method/SendVideoNoteTest.php +++ b/tests/Method/SendVideoNoteTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\SendVideoNote; use Phptg\BotApi\Transport\HttpMethod; @@ -36,8 +35,8 @@ public function testBase(): void public function testFull(): void { - $video = new InputFile((new StreamFactory())->createStream('test'), 'test.mp4'); - $thumbnail = new InputFile((new StreamFactory())->createStream('test'), 'test.jpg'); + $video = new InputFile(null, 'test.mp4'); + $thumbnail = new InputFile(null, 'test.jpg'); $replyParameters = new ReplyParameters(23); $replyMarkup = new ForceReply(); $method = new SendVideoNote( diff --git a/tests/Method/SendVideoTest.php b/tests/Method/SendVideoTest.php index c88b483a..7bf94289 100644 --- a/tests/Method/SendVideoTest.php +++ b/tests/Method/SendVideoTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\SendVideo; use Phptg\BotApi\Transport\HttpMethod; @@ -37,8 +36,8 @@ public function testBase(): void public function testFull(): void { - $video = new InputFile((new StreamFactory())->createStream('test'), 'test.mp4'); - $thumbnail = new InputFile((new StreamFactory())->createStream('test'), 'test.jpg'); + $video = new InputFile(null, 'test.mp4'); + $thumbnail = new InputFile(null, 'test.jpg'); $entity = new MessageEntity('bold', 0, 5); $replyParameters = new ReplyParameters(23); $replyMarkup = new ForceReply(); diff --git a/tests/Method/SendVoiceTest.php b/tests/Method/SendVoiceTest.php index c8814f0d..86645761 100644 --- a/tests/Method/SendVoiceTest.php +++ b/tests/Method/SendVoiceTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\SendVoice; use Phptg\BotApi\Transport\HttpMethod; @@ -37,7 +36,7 @@ public function testBase(): void public function testFull(): void { - $voice = new InputFile((new StreamFactory())->createStream('test'), 'test.mp3'); + $voice = new InputFile(null, 'test.mp3'); $entity = new MessageEntity('bold', 0, 5); $replyParameters = new ReplyParameters(23); $replyMarkup = new ForceReply(); diff --git a/tests/Method/SetBusinessAccountProfilePhotoTest.php b/tests/Method/SetBusinessAccountProfilePhotoTest.php index ed257b06..f97ce507 100644 --- a/tests/Method/SetBusinessAccountProfilePhotoTest.php +++ b/tests/Method/SetBusinessAccountProfilePhotoTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Method\SetBusinessAccountProfilePhoto; @@ -20,7 +19,7 @@ final class SetBusinessAccountProfilePhotoTest extends TestCase { public function testBase(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $photo = new InputProfilePhotoStatic($file); $method = new SetBusinessAccountProfilePhoto('bcid1', $photo); @@ -38,7 +37,7 @@ public function testBase(): void public function testFull(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $photo = new InputProfilePhotoStatic($file); $method = new SetBusinessAccountProfilePhoto('bcid1', $photo, true); @@ -55,7 +54,7 @@ public function testFull(): void public function testPrepareResult(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $photo = new InputProfilePhotoStatic($file); $method = new SetBusinessAccountProfilePhoto('bcid1', $photo); diff --git a/tests/Method/Sticker/AddStickerToSetTest.php b/tests/Method/Sticker/AddStickerToSetTest.php index 957b6481..c309bfd5 100644 --- a/tests/Method/Sticker/AddStickerToSetTest.php +++ b/tests/Method/Sticker/AddStickerToSetTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method\Sticker; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\Sticker\AddStickerToSet; use Phptg\BotApi\Transport\HttpMethod; @@ -19,7 +18,7 @@ final class AddStickerToSetTest extends TestCase { public function testBase(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $inputSticker = new InputSticker($file, 'static', ['😀']); $method = new AddStickerToSet(1, 'test', $inputSticker); diff --git a/tests/Method/Sticker/ReplaceStickerInSetTest.php b/tests/Method/Sticker/ReplaceStickerInSetTest.php index e369d9bb..bd48bf5c 100644 --- a/tests/Method/Sticker/ReplaceStickerInSetTest.php +++ b/tests/Method/Sticker/ReplaceStickerInSetTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method\Sticker; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\Sticker\ReplaceStickerInSet; use Phptg\BotApi\Transport\HttpMethod; @@ -19,7 +18,7 @@ final class ReplaceStickerInSetTest extends TestCase { public function testBase(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $inputSticker = new InputSticker($file, 'static', ['😀']); $method = new ReplaceStickerInSet(1, 'test', 'oldid', $inputSticker); diff --git a/tests/Method/Sticker/SendStickerTest.php b/tests/Method/Sticker/SendStickerTest.php index 8ab4b8ce..12adfb03 100644 --- a/tests/Method/Sticker/SendStickerTest.php +++ b/tests/Method/Sticker/SendStickerTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method\Sticker; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\Sticker\SendSticker; use Phptg\BotApi\Transport\HttpMethod; @@ -36,7 +35,7 @@ public function testBase(): void public function testFull(): void { - $sticker = new InputFile((new StreamFactory())->createStream()); + $sticker = new InputFile(null); $replyParameters = new ReplyParameters(23); $replyMarkup = new ForceReply(); $method = new SendSticker( diff --git a/tests/Method/Sticker/SetStickerSetThumbnailTest.php b/tests/Method/Sticker/SetStickerSetThumbnailTest.php index 318723be..54779a9c 100644 --- a/tests/Method/Sticker/SetStickerSetThumbnailTest.php +++ b/tests/Method/Sticker/SetStickerSetThumbnailTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method\Sticker; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\Sticker\SetStickerSetThumbnail; use Phptg\BotApi\Transport\HttpMethod; @@ -34,7 +33,7 @@ public function testBase(): void public function testFull(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $method = new SetStickerSetThumbnail('animals_by_my_bot', 123, 'static', $file); assertSame(HttpMethod::POST, $method->getHttpMethod()); diff --git a/tests/Method/Sticker/UploadStickerFileTest.php b/tests/Method/Sticker/UploadStickerFileTest.php index af086aee..38602b2a 100644 --- a/tests/Method/Sticker/UploadStickerFileTest.php +++ b/tests/Method/Sticker/UploadStickerFileTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method\Sticker; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\Sticker\UploadStickerFile; use Phptg\BotApi\Transport\HttpMethod; @@ -17,7 +16,7 @@ final class UploadStickerFileTest extends TestCase { public function testBase(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $method = new UploadStickerFile(1, $file, 'static'); assertSame(HttpMethod::POST, $method->getHttpMethod()); @@ -34,7 +33,7 @@ public function testBase(): void public function testPrepareResult(): void { - $method = new UploadStickerFile(1, new InputFile((new StreamFactory())->createStream()), 'static'); + $method = new UploadStickerFile(1, new InputFile(null), 'static'); $preparedResult = TestHelper::createSuccessStubApi([ 'file_id' => 'f1', diff --git a/tests/Method/UpdatingMessage/EditMessageMediaTest.php b/tests/Method/UpdatingMessage/EditMessageMediaTest.php index 898367a1..7dba0326 100644 --- a/tests/Method/UpdatingMessage/EditMessageMediaTest.php +++ b/tests/Method/UpdatingMessage/EditMessageMediaTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method\UpdatingMessage; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\UpdatingMessage\EditMessageMedia; use Phptg\BotApi\Transport\HttpMethod; @@ -40,7 +39,7 @@ public function testBase(): void public function testFull(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $media = new InputMediaPhoto($file); $replyMarkup = new InlineKeyboardMarkup([[new InlineKeyboardButton('hello')]]); $method = new EditMessageMedia( diff --git a/tests/TelegramBotApiTest.php b/tests/TelegramBotApiTest.php index c24324eb..64ee748b 100644 --- a/tests/TelegramBotApiTest.php +++ b/tests/TelegramBotApiTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests; -use HttpSoft\Message\StreamFactory; use LogicException; use Phptg\BotApi\Type\MessageEntity; use PHPUnit\Framework\Attributes\DataProvider; @@ -946,7 +945,7 @@ public function testEditStory(): void 'business_connection_id', 456, new InputStoryContentPhoto( - new InputFile((new StreamFactory())->createStream()), + new InputFile(null), ), ); @@ -1469,9 +1468,7 @@ public function testPostMethodWithFiles(): void ]); $api = new TelegramBotApi('stub-token', transport: $transport); - $file = new InputFile( - (new StreamFactory())->createStream('test1'), - ); + $file = new InputFile(null); $api->sendDocument( 'id1', $file, @@ -1612,7 +1609,7 @@ public function testPostStory(): void $result = $api->postStory( 'business_connection_id', new InputStoryContentPhoto( - new InputFile((new StreamFactory())->createStream()), + new InputFile(null), ), 86400, ); @@ -1806,7 +1803,7 @@ public function testSetBusinessAccountProfilePhoto(): void $result = $api->setBusinessAccountProfilePhoto( 'biz123', new InputProfilePhotoStatic( - new InputFile((new StreamFactory())->createStream()), + new InputFile(null), ), ); @@ -2224,7 +2221,7 @@ public function testSetChatPhoto(): void { $api = TestHelper::createSuccessStubApi(true); - $result = $api->setChatPhoto(12, new InputFile((new StreamFactory())->createStream())); + $result = $api->setChatPhoto(12, new InputFile(null)); assertTrue($result); } @@ -2534,7 +2531,7 @@ public function testUploadStickerFile(): void 'file_path' => 'path/to/file', ]); - $result = $api->uploadStickerFile(1, new InputFile((new StreamFactory())->createStream()), 'static'); + $result = $api->uploadStickerFile(1, new InputFile(null), 'static'); assertInstanceOf(File::class, $result); assertSame('f1', $result->fileId); diff --git a/tests/Transport/CurlTransport/CurlTransportTest.php b/tests/Transport/CurlTransport/CurlTransportTest.php index 50fdfadd..0d7b6873 100644 --- a/tests/Transport/CurlTransport/CurlTransportTest.php +++ b/tests/Transport/CurlTransport/CurlTransportTest.php @@ -6,7 +6,6 @@ use CurlShareHandle; use CURLStringFile; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use RuntimeException; use Throwable; diff --git a/tests/Transport/NativeTransport/NativeTransportTest.php b/tests/Transport/NativeTransport/NativeTransportTest.php index fabce3ce..5358ddd1 100644 --- a/tests/Transport/NativeTransport/NativeTransportTest.php +++ b/tests/Transport/NativeTransport/NativeTransportTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Transport\NativeTransport; -use HttpSoft\Message\StreamFactory; use Phptg\BotApi\Transport\InputFileData; use PHPUnit\Framework\TestCase; use RuntimeException; @@ -16,8 +15,6 @@ use function PHPUnit\Framework\assertMatchesRegularExpression; use function PHPUnit\Framework\assertSame; use function PHPUnit\Framework\assertStringContainsString; -use function PHPUnit\Framework\assertStringEndsWith; -use function PHPUnit\Framework\assertStringStartsWith; use function PHPUnit\Framework\assertTrue; final class NativeTransportTest extends TestCase diff --git a/tests/Type/InputFileTest.php b/tests/Type/InputFileTest.php index 3d2e619d..c0e88a69 100644 --- a/tests/Type/InputFileTest.php +++ b/tests/Type/InputFileTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use RuntimeException; use Throwable; @@ -19,19 +18,17 @@ final class InputFileTest extends TestCase { public function testBase(): void { - $stream = (new StreamFactory())->createStream('test'); - $file = new InputFile($stream); + $file = new InputFile('test'); - assertSame($stream, $file->resource); + assertSame('test', $file->resource); assertNull($file->filename); } public function testFilled(): void { - $stream = (new StreamFactory())->createStream('test'); - $file = new InputFile($stream, 'file.txt'); + $file = new InputFile('test', 'file.txt'); - assertSame($stream, $file->resource); + assertSame('test', $file->resource); assertSame('file.txt', $file->filename); } diff --git a/tests/Type/InputMediaAnimationTest.php b/tests/Type/InputMediaAnimationTest.php index d943ef14..8cabe3c7 100644 --- a/tests/Type/InputMediaAnimationTest.php +++ b/tests/Type/InputMediaAnimationTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -42,8 +41,8 @@ public function testBase(): void public function testFull(): void { - $media = new InputFile((new StreamFactory())->createStream()); - $thumbnail = new InputFile((new StreamFactory())->createStream()); + $media = new InputFile(null); + $thumbnail = new InputFile(null); $entity = new MessageEntity('bold', 0, 4); $inputMedia = new InputMediaAnimation( $media, diff --git a/tests/Type/InputMediaAudioTest.php b/tests/Type/InputMediaAudioTest.php index bc65de32..7611e29d 100644 --- a/tests/Type/InputMediaAudioTest.php +++ b/tests/Type/InputMediaAudioTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -42,8 +41,8 @@ public function testBase(): void public function testFull(): void { - $media = new InputFile((new StreamFactory())->createStream()); - $thumbnail = new InputFile((new StreamFactory())->createStream()); + $media = new InputFile(null); + $thumbnail = new InputFile(null); $entity = new MessageEntity('bold', 0, 4); $inputMedia = new InputMediaAudio( $media, diff --git a/tests/Type/InputMediaDocumentTest.php b/tests/Type/InputMediaDocumentTest.php index 82a1b2da..e4a5464a 100644 --- a/tests/Type/InputMediaDocumentTest.php +++ b/tests/Type/InputMediaDocumentTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -42,8 +41,8 @@ public function testBase(): void public function testFull(): void { - $media = new InputFile((new StreamFactory())->createStream()); - $thumbnail = new InputFile((new StreamFactory())->createStream()); + $media = new InputFile(null); + $thumbnail = new InputFile(null); $entity = new MessageEntity('bold', 0, 4); $inputMedia = new InputMediaDocument( $media, diff --git a/tests/Type/InputMediaPhotoTest.php b/tests/Type/InputMediaPhotoTest.php index 78c2b84b..214402cc 100644 --- a/tests/Type/InputMediaPhotoTest.php +++ b/tests/Type/InputMediaPhotoTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -42,7 +41,7 @@ public function testBase(): void public function testFull(): void { - $media = new InputFile((new StreamFactory())->createStream()); + $media = new InputFile(null); $entity = new MessageEntity('bold', 0, 4); $inputMedia = new InputMediaPhoto( $media, diff --git a/tests/Type/InputMediaVideoTest.php b/tests/Type/InputMediaVideoTest.php index e154310a..a07630f9 100644 --- a/tests/Type/InputMediaVideoTest.php +++ b/tests/Type/InputMediaVideoTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -42,9 +41,9 @@ public function testBase(): void public function testFull(): void { - $media = new InputFile((new StreamFactory())->createStream()); - $thumbnail = new InputFile((new StreamFactory())->createStream()); - $cover = new InputFile((new StreamFactory())->createStream()); + $media = new InputFile(null); + $thumbnail = new InputFile(null); + $cover = new InputFile(null); $entity = new MessageEntity('bold', 0, 4); $inputMedia = new InputMediaVideo( $media, diff --git a/tests/Type/InputPaidMediaPhotoTest.php b/tests/Type/InputPaidMediaPhotoTest.php index 3dba08a5..739ceda8 100644 --- a/tests/Type/InputPaidMediaPhotoTest.php +++ b/tests/Type/InputPaidMediaPhotoTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -41,7 +40,7 @@ public function testBase(): void public function testFull(): void { - $media = new InputFile((new StreamFactory())->createStream()); + $media = new InputFile(null); $inputMedia = new InputPaidMediaPhoto($media); assertSame('photo', $inputMedia->getType()); diff --git a/tests/Type/InputPaidMediaVideoTest.php b/tests/Type/InputPaidMediaVideoTest.php index 27af7257..043e1acb 100644 --- a/tests/Type/InputPaidMediaVideoTest.php +++ b/tests/Type/InputPaidMediaVideoTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -41,9 +40,9 @@ public function testBase(): void public function testFull(): void { - $media = new InputFile((new StreamFactory())->createStream()); - $thumbnail = new InputFile((new StreamFactory())->createStream()); - $cover = new InputFile((new StreamFactory())->createStream()); + $media = new InputFile(null); + $thumbnail = new InputFile(null); + $cover = new InputFile(null); $inputMedia = new InputPaidMediaVideo( $media, $thumbnail, diff --git a/tests/Type/InputProfilePhotoAnimatedTest.php b/tests/Type/InputProfilePhotoAnimatedTest.php index b79bb96a..f5dfa90c 100644 --- a/tests/Type/InputProfilePhotoAnimatedTest.php +++ b/tests/Type/InputProfilePhotoAnimatedTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -18,7 +17,7 @@ final class InputProfilePhotoAnimatedTest extends TestCase { public function testBase(): void { - $animation = new InputFile((new StreamFactory())->createStream()); + $animation = new InputFile(null); $type = new InputProfilePhotoAnimated($animation); assertInstanceOf(InputProfilePhoto::class, $type); @@ -43,7 +42,7 @@ public function testBase(): void public function testFull(): void { - $animation = new InputFile((new StreamFactory())->createStream()); + $animation = new InputFile(null); $type = new InputProfilePhotoAnimated($animation, 2.5); assertInstanceOf(InputProfilePhoto::class, $type); diff --git a/tests/Type/InputProfilePhotoStaticTest.php b/tests/Type/InputProfilePhotoStaticTest.php index b1fee516..428e7446 100644 --- a/tests/Type/InputProfilePhotoStaticTest.php +++ b/tests/Type/InputProfilePhotoStaticTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -18,7 +17,7 @@ final class InputProfilePhotoStaticTest extends TestCase { public function testBase(): void { - $photo = new InputFile((new StreamFactory())->createStream()); + $photo = new InputFile(null); $type = new InputProfilePhotoStatic($photo); assertInstanceOf(InputProfilePhoto::class, $type); diff --git a/tests/Type/InputStoryContentPhotoTest.php b/tests/Type/InputStoryContentPhotoTest.php index 51b8e40a..a29fc760 100644 --- a/tests/Type/InputStoryContentPhotoTest.php +++ b/tests/Type/InputStoryContentPhotoTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -18,7 +17,7 @@ final class InputStoryContentPhotoTest extends TestCase { public function testBase(): void { - $photo = new InputFile((new StreamFactory())->createStream()); + $photo = new InputFile(null); $type = new InputStoryContentPhoto($photo); assertInstanceOf(InputStoryContent::class, $type); diff --git a/tests/Type/InputStoryContentVideoTest.php b/tests/Type/InputStoryContentVideoTest.php index 941279c9..00c07006 100644 --- a/tests/Type/InputStoryContentVideoTest.php +++ b/tests/Type/InputStoryContentVideoTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Type\InputFile; @@ -19,7 +18,7 @@ final class InputStoryContentVideoTest extends TestCase { public function testBase(): void { - $video = new InputFile((new StreamFactory())->createStream()); + $video = new InputFile(null); $type = new InputStoryContentVideo($video); assertInstanceOf(InputStoryContent::class, $type); @@ -44,7 +43,7 @@ public function testBase(): void public function testFull(): void { - $video = new InputFile((new StreamFactory())->createStream()); + $video = new InputFile(null); $type = new InputStoryContentVideo($video, 10.5, 2.5, true); assertInstanceOf(InputStoryContent::class, $type); diff --git a/tests/Type/Sticker/InputStickerTest.php b/tests/Type/Sticker/InputStickerTest.php index 0ac22c17..503777fc 100644 --- a/tests/Type/Sticker/InputStickerTest.php +++ b/tests/Type/Sticker/InputStickerTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Type\Sticker; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Constant\Sticker\StickerFormat; use Phptg\BotApi\FileCollector; @@ -48,7 +47,7 @@ public function testBase(): void public function testFull(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $maskPosition = new MaskPosition('forehead', 0.5, 0.6, 0.7); $inputSticker = new InputSticker( $file, diff --git a/tests/Type/Update/UpdateTest.php b/tests/Type/Update/UpdateTest.php index 7da1d705..9d887696 100644 --- a/tests/Type/Update/UpdateTest.php +++ b/tests/Type/Update/UpdateTest.php @@ -4,11 +4,8 @@ namespace Phptg\BotApi\Tests\Type\Update; -use HttpSoft\Message\StreamTrait; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; -use Psr\Http\Message\ServerRequestInterface; -use Psr\Http\Message\StreamInterface; use Throwable; use Phptg\BotApi\ParseResult\TelegramParseResultException; use Phptg\BotApi\ParseResult\ObjectFactory; diff --git a/tests/WebhookResponse/WebhookResponseTest.php b/tests/WebhookResponse/WebhookResponseTest.php index 70d9ad0b..647671c5 100644 --- a/tests/WebhookResponse/WebhookResponseTest.php +++ b/tests/WebhookResponse/WebhookResponseTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\WebhookResponse; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\Method\SendMessage; use Phptg\BotApi\Method\SendPhoto; @@ -40,7 +39,7 @@ public function testMethodWithInputFile(): void { $method = new SendPhoto( chatId: 'x1', - photo: new InputFile((new StreamFactory())->createStream()), + photo: new InputFile(null), ); $webhookResponse = new WebhookResponse($method); From 1d2145a04ec9171b0c21a6e733e3c5fd47416c83 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 7 Feb 2026 21:34:53 +0300 Subject: [PATCH 04/14] docs --- CHANGELOG.md | 6 +++++ docs/logging.md | 3 --- docs/resource-readers.md | 4 +-- docs/transport.md | 50 +++-------------------------------- docs/webhook-handling.md | 56 +--------------------------------------- 5 files changed, 11 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48edf35d..017b6d96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Telegram Bot API for PHP Change Log +## 0.15 under development + +- Chg #186: Remove `PsrTransport`, `PsrWebhookResponseFactory` and `StreamResourceReader` classes. +- Chg #186: Remove `Update::fromServerRequest()` method. +- Chg #186: Remove PSR composer dependencies. + ## 0.14 February 7, 2026 - New #182: Introduce resource readers that handle reading content from different types of resources stored in diff --git a/docs/logging.md b/docs/logging.md index 993caae3..27d751e5 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -24,17 +24,14 @@ $api = new TelegramBotApi($token, logger: $logger); You can use logger on create `Update` object also: ```php -use Psr\Http\Message\ServerRequestInterface; use Psr\Log\LoggerInterface; use Phptg\BotApi\Type\Update\Update; /** - * @var ServerRequestInterface $request * @var string $jsonString * @var LoggerInterface $logger */ -$update = Update::fromServerRequest($request, $logger); $update = Update::fromJson($jsonString, $logger); ``` diff --git a/docs/resource-readers.md b/docs/resource-readers.md index 5ce478c4..a6a4a8c3 100644 --- a/docs/resource-readers.md +++ b/docs/resource-readers.md @@ -6,11 +6,9 @@ and uses the first one that supports the resource type. ## Built-in readers -The package provides two built-in resource readers: +The package provides one built-in resource reader: - `NativeResourceReader` — handles native PHP stream resources created by functions like `fopen()`, `tmpfile()`, etc. -- `StreamResourceReader` — handles PSR-7 `StreamInterface` instances, commonly used in PSR-7 HTTP message - implementations. ## Custom resource readers diff --git a/docs/transport.md b/docs/transport.md index 072dd644..6d0fd840 100644 --- a/docs/transport.md +++ b/docs/transport.md @@ -4,7 +4,7 @@ By default `TelegramBotApi` uses cURL to make requests to the Telegram Bot API a But you can use any other transport implementation that implements the `Phptg\BotApi\Transport\TransportInterface` interface. -Out of the box, available three transport implementations: cURL, native and PSR. +Out of the box, available two transport implementations: cURL and native. ## cURL @@ -29,7 +29,7 @@ $api = new TelegramBotApi($token, transport: $transport); Constructor parameters: - `$resourceReaders` — list of [resource readers](resource-readers.md) to handle different resource types. By default, - includes `NativeResourceReader` and `StreamResourceReader`. + includes `NativeResourceReader`. ## Native @@ -58,7 +58,7 @@ Constructor parameters: - `$mimeTypeResolver` — MIME type resolver for determining file types. Defaults to `ApacheMimeTypeResolver`. - `$resourceReaders` — List of [resource readers](resource-readers.md) to handle different resource types. By default, - includes `NativeResourceReader` and `StreamResourceReader`. + includes `NativeResourceReader`. Available MIME type resolvers: @@ -67,47 +67,3 @@ Available MIME type resolvers: by default); - `CustomMimeTypeResolver` - based on file extension and custom MIME types map; - `CompositeMimeTypeResolver` - allows to combine multiple resolvers into one. - -## PSR - -PSR transport requires the [PSR-18](https://www.php-fig.org/psr/psr-18/) HTTP client and [PSR-17](https://www.php-fig.org/psr/psr-17/) HTTP factories. - -For example, you can use the [php-http/curl-client](https://github.com/php-http/curl-client) and [httpsoft/http-message](https://github.com/httpsoft/http-message): - -```shell -composer require php-http/curl-client httpsoft/http-message -``` - -General usage: - -```php -use Http\Client\Curl\Client; -use HttpSoft\Message\RequestFactory; -use HttpSoft\Message\ResponseFactory; -use HttpSoft\Message\StreamFactory; -use Phptg\BotApi\TelegramBotApi; -use Phptg\BotApi\Transport\PsrTransport; - -$streamFactory = new StreamFactory(); -$responseFactory = new ResponseFactory(); -$requestFactory = new RequestFactory(); -$client = new Client($responseFactory, $streamFactory); - -// Telegram bot authentication token -$token = '110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw'; - -$transport = new PsrTransport( - $client, - $requestFactory, - $streamFactory, -); - -$api = new TelegramBotApi($token, transport: $transport); -``` - -Constructor parameters: - -- `$client` — PSR-18 HTTP client; -- `$requestFactory` — PSR-17 HTTP request factory; -- `$streamFactory` — PSR-17 HTTP stream factory; - diff --git a/docs/webhook-handling.md b/docs/webhook-handling.md index 0205ae57..34235b7e 100644 --- a/docs/webhook-handling.md +++ b/docs/webhook-handling.md @@ -6,11 +6,10 @@ This guide explains how to handle incoming webhook updates from Telegram and how You can create an `Update` object by several ways: -- [from PSR-7 request](#from-psr-7-request), - [from JSON string](#from-json-string), - [via constructor](#via-constructor). -If `Update` created by `fromJson()` or `fromServerRequest()` method, you can get raw data via `getRaw()` method: +If `Update` created by `fromJson()` method, you can get raw data via `getRaw()` method: ```php /** @@ -55,26 +54,6 @@ $raw = $update->getRaw(); $raw = $update->getRaw(decoded: true); ``` -### From PSR-7 request - -Creating `Update` object from the incoming webhook PSR-7 request: - -```php -use Psr\Http\Message\ServerRequestInterface; -use Phptg\BotApi\ParseResult\TelegramParseResultException; -use Phptg\BotApi\Type\Update\Update; - -/** - * @var ServerRequestInterface $request - */ - -try { - $update = Update::fromServerRequest($request); -} catch (TelegramParseResultException $e) { - // ... -} -``` - ### From JSON string Creating `Update` object from JSON string received from POST request body: @@ -137,39 +116,6 @@ if ($webhookResponse->isSupported()) { } ``` -### PSR-7 response factory - -The `PsrWebhookResponseFactory` creates PSR-7 compliant HTTP responses for webhook handlers: - -```php -use Psr\Http\Message\ResponseFactoryInterface; -use Psr\Http\Message\StreamFactoryInterface; -use Phptg\BotApi\Method\SendMessage; -use Phptg\BotApi\WebhookResponse\PsrWebhookResponseFactory; -use Phptg\BotApi\WebhookResponse\WebhookResponse; - -/** - * @var ResponseFactoryInterface $responseFactory - * @var StreamFactoryInterface $streamFactory - */ - -$factory = new PsrWebhookResponseFactory($responseFactory, $streamFactory); - -// Create response from WebhookResponse object -$webhookResponse = new WebhookResponse(new SendMessage(chatId: 12345, text: 'Hello!')); -$response = $factory->create($webhookResponse); - -// Or create response directly from method, if you are sure that InputFile is not used -$method = new SendMessage(chatId: 12345, text: 'Hello!'); -$response = $factory->byMethod($method); -``` - -The factory automatically: - -- encodes the data as JSON; -- sets the `Content-Type` header to `application/json; charset=utf-8`; -- sets the `Content-Length` header. - ### JSON response factory The `JsonWebhookResponseFactory` creates JSON strings for webhook responses: From 3b6fe583001cd752ad6df9d4dfe0e25621ac1dc7 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 7 Feb 2026 21:42:01 +0300 Subject: [PATCH 05/14] improve --- docs/resource-readers.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/resource-readers.md b/docs/resource-readers.md index a6a4a8c3..ba81de49 100644 --- a/docs/resource-readers.md +++ b/docs/resource-readers.md @@ -10,6 +10,9 @@ The package provides one built-in resource reader: - `NativeResourceReader` — handles native PHP stream resources created by functions like `fopen()`, `tmpfile()`, etc. +Also, the [phptg/transport-psr](https://github.com/phptg/transport-psr) package provides `StreamResourceReader`, +which adds support for PSR-7 `StreamInterface` resources. + ## Custom resource readers You can create custom resource readers by implementing the `ResourceReaderInterface`. This is useful when you need From bcd5e04893470211952aacca95d15df4f3f45c32 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 7 Feb 2026 21:43:52 +0300 Subject: [PATCH 06/14] improve --- docs/resource-readers.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/resource-readers.md b/docs/resource-readers.md index ba81de49..ed377ff3 100644 --- a/docs/resource-readers.md +++ b/docs/resource-readers.md @@ -10,8 +10,9 @@ The package provides one built-in resource reader: - `NativeResourceReader` — handles native PHP stream resources created by functions like `fopen()`, `tmpfile()`, etc. -Also, the [phptg/transport-psr](https://github.com/phptg/transport-psr) package provides `StreamResourceReader`, -which adds support for PSR-7 `StreamInterface` resources. +## Additional readers + +- `StreamResourceReader` — handles PSR-7 `StreamInterface` resources. Provided by the [phptg/transport-psr](https://github.com/phptg/transport-psr) package. ## Custom resource readers From 965740ce808fc04fad2e23b3ec293a0a1eb6bd0b Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 7 Feb 2026 21:53:57 +0300 Subject: [PATCH 07/14] improve --- docs/transport.md | 3 +++ docs/webhook-handling.md | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/docs/transport.md b/docs/transport.md index 6d0fd840..b509fa2d 100644 --- a/docs/transport.md +++ b/docs/transport.md @@ -6,6 +6,9 @@ the `Phptg\BotApi\Transport\TransportInterface` interface. Out of the box, available two transport implementations: cURL and native. +Additionally, the [phptg/transport-psr](https://github.com/phptg/transport-psr) package provides `PsrTransport` +based on PSR-18 HTTP client and PSR-17 HTTP factories. + ## cURL The `CurlTransport` class is a transport implementation for making requests to the Telegram Bot API using diff --git a/docs/webhook-handling.md b/docs/webhook-handling.md index 34235b7e..2745baf8 100644 --- a/docs/webhook-handling.md +++ b/docs/webhook-handling.md @@ -9,6 +9,9 @@ You can create an `Update` object by several ways: - [from JSON string](#from-json-string), - [via constructor](#via-constructor). +Additionally, the [phptg/transport-psr](https://github.com/phptg/transport-psr) package provides `PsrUpdateFactory` +that creates `Update` object from a PSR-7 `ServerRequestInterface`. + If `Update` created by `fromJson()` method, you can get raw data via `getRaw()` method: ```php @@ -140,6 +143,9 @@ header('Content-Type: application/json; charset=utf-8'); echo $json; ``` +Additionally, the [phptg/transport-psr](https://github.com/phptg/transport-psr) package provides +`PsrWebhookResponseFactory` that creates a PSR-7 `ResponseInterface` for webhook responses. + ### Limitations Webhook responses have an important limitation: they **do not support file uploads** (methods using `InputFile`). From 3015dbb20b8c4de7b2abc83ba6c863852843cd29 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 7 Feb 2026 21:57:54 +0300 Subject: [PATCH 08/14] improve --- docs/webhook-handling.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/webhook-handling.md b/docs/webhook-handling.md index 2745baf8..1cb4a8fc 100644 --- a/docs/webhook-handling.md +++ b/docs/webhook-handling.md @@ -119,7 +119,13 @@ if ($webhookResponse->isSupported()) { } ``` -### JSON response factory +### Response factories + +The package provides a built-in `JsonWebhookResponseFactory` that creates JSON strings for webhook responses. +Additionally, the [phptg/transport-psr](https://github.com/phptg/transport-psr) package provides +`PsrWebhookResponseFactory` that creates a PSR-7 `ResponseInterface`. + +#### JSON The `JsonWebhookResponseFactory` creates JSON strings for webhook responses: @@ -143,9 +149,6 @@ header('Content-Type: application/json; charset=utf-8'); echo $json; ``` -Additionally, the [phptg/transport-psr](https://github.com/phptg/transport-psr) package provides -`PsrWebhookResponseFactory` that creates a PSR-7 `ResponseInterface` for webhook responses. - ### Limitations Webhook responses have an important limitation: they **do not support file uploads** (methods using `InputFile`). From dbc4b12e30f0994f134bd1593834e6e69474d792 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 7 Feb 2026 22:00:10 +0300 Subject: [PATCH 09/14] improve --- docs/webhook-handling.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/webhook-handling.md b/docs/webhook-handling.md index 1cb4a8fc..b23693df 100644 --- a/docs/webhook-handling.md +++ b/docs/webhook-handling.md @@ -122,10 +122,11 @@ if ($webhookResponse->isSupported()) { ### Response factories The package provides a built-in `JsonWebhookResponseFactory` that creates JSON strings for webhook responses. + Additionally, the [phptg/transport-psr](https://github.com/phptg/transport-psr) package provides `PsrWebhookResponseFactory` that creates a PSR-7 `ResponseInterface`. -#### JSON +#### JSON response factory The `JsonWebhookResponseFactory` creates JSON strings for webhook responses: From 93f0d0843da513a8082ee142e5b33d72bd7bd011 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 7 Feb 2026 22:05:08 +0300 Subject: [PATCH 10/14] kill mutant --- tests/Transport/InputFileDataTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/Transport/InputFileDataTest.php b/tests/Transport/InputFileDataTest.php index 846e720f..8a0fea68 100644 --- a/tests/Transport/InputFileDataTest.php +++ b/tests/Transport/InputFileDataTest.php @@ -5,6 +5,7 @@ namespace Phptg\BotApi\Tests\Transport; use LogicException; +use Phptg\BotApi\Tests\Support\StubResourceReader; use Phptg\BotApi\Transport\InputFileData; use Phptg\BotApi\Type\InputFile; use PHPUnit\Framework\TestCase; @@ -19,4 +20,15 @@ public function testWithoutReader(): void $this->expectExceptionMessage('No suitable resource reader found.'); new InputFileData($file, []); } + + public function testExtensionAndBasenameAreNullForUri(): void + { + $reader = new StubResourceReader(uri: 'https://example.com/file.txt'); + + $file = new InputFile('resource'); + $data = new InputFileData($file, [$reader]); + + $this->assertNull($data->extension()); + $this->assertNull($data->basename()); + } } From 5e31236ee993d890a4efcfcbe73ebdab56ecd63a Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 7 Feb 2026 22:22:00 +0300 Subject: [PATCH 11/14] improve --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b2e10e60..4098b470 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ The package provides a simple and convenient way to interact with the Telegram B ✔️ Telegram Bot API 9.3 (December 31, 2025) is **fully supported**. +♻️ **Zero dependencies** — no third-party libraries, only native PHP. + > [!IMPORTANT] > This project is developed and maintained by [Sergei Predvoditelev](https://github.com/vjik). > Community support helps keep the project actively developed and well maintained. From 2dabb9afae7da91387d0bb7ff034a863ca3f7a29 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 10 Feb 2026 12:53:12 +0300 Subject: [PATCH 12/14] fix --- tests/Method/SetMyProfilePhotoTest.php | 5 ++--- tests/TelegramBotApiTest.php | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/Method/SetMyProfilePhotoTest.php b/tests/Method/SetMyProfilePhotoTest.php index 17f7197d..1740d5f6 100644 --- a/tests/Method/SetMyProfilePhotoTest.php +++ b/tests/Method/SetMyProfilePhotoTest.php @@ -4,7 +4,6 @@ namespace Phptg\BotApi\Tests\Method; -use HttpSoft\Message\StreamFactory; use PHPUnit\Framework\TestCase; use Phptg\BotApi\FileCollector; use Phptg\BotApi\Method\SetMyProfilePhoto; @@ -20,7 +19,7 @@ final class SetMyProfilePhotoTest extends TestCase { public function testBase(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $photo = new InputProfilePhotoStatic($file); $method = new SetMyProfilePhoto($photo); @@ -37,7 +36,7 @@ public function testBase(): void public function testPrepareResult(): void { - $file = new InputFile((new StreamFactory())->createStream()); + $file = new InputFile(null); $photo = new InputProfilePhotoStatic($file); $method = new SetMyProfilePhoto($photo); diff --git a/tests/TelegramBotApiTest.php b/tests/TelegramBotApiTest.php index 782cb6f0..8e159c0f 100644 --- a/tests/TelegramBotApiTest.php +++ b/tests/TelegramBotApiTest.php @@ -2337,7 +2337,7 @@ public function testSetMyProfilePhoto(): void $result = $api->setMyProfilePhoto( new InputProfilePhotoStatic( - new InputFile((new StreamFactory())->createStream()), + new InputFile(null), ), ); From cabec2191bebcdf7dbcccbca49ed07d7f87d22dc Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 10 Feb 2026 12:53:53 +0300 Subject: [PATCH 13/14] fix --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4e8ea92..8ea98c3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Chg #186: Remove `PsrTransport`, `PsrWebhookResponseFactory` and `StreamResourceReader` classes. - Chg #186: Remove `Update::fromServerRequest()` method. - Chg #186: Remove PSR composer dependencies. + ## 0.14.1 February 9, 2026 - New #186: Add `SetMyProfilePhoto`, `RemoveMyProfilePhoto` and `GetUserProfileAudios` methods. From 7ac74b4d0b951f74a8f18e877c949987ae7b6b25 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 28 Feb 2026 21:17:36 +0300 Subject: [PATCH 14/14] changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77f211c8..82fa3e21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,11 @@ # Telegram Bot API for PHP Change Log -## 0.15 under development +## 0.16 under development - Chg #186: Remove `PsrTransport`, `PsrWebhookResponseFactory` and `StreamResourceReader` classes. - Chg #186: Remove `Update::fromServerRequest()` method. - Chg #186: Remove PSR composer dependencies. + ## 0.15 February 28, 2026 - Chg #187: Change `TransportInterface::downloadFile()` signature — remove `$stream` parameter, method now returns