From 82055edc5985bbf6b0fe2c2b93c0a216b75e5c14 Mon Sep 17 00:00:00 2001 From: guanguans Date: Fri, 15 Nov 2024 11:16:48 +0800 Subject: [PATCH] test(Response): Refactor saveAs method and add new test case - Remove unused parameter `closeResource` from `saveAs` method. - Ensure resource is closed after use. - Add a new test case to validate conversion of response to resource. - Improve clarity and maintainability of the response handling. --- composer-require-checker.json | 1 + src/Foundation/Response.php | 92 ++++++++++++++----------------- tests/Foundation/ResponseTest.php | 20 +++---- 3 files changed, 52 insertions(+), 61 deletions(-) diff --git a/composer-require-checker.json b/composer-require-checker.json index 752b5b8..d95d53c 100644 --- a/composer-require-checker.json +++ b/composer-require-checker.json @@ -51,6 +51,7 @@ "PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode", "Psr\\Http\\Message\\RequestInterface", "Psr\\Http\\Message\\ResponseInterface", + "Psr\\Http\\Message\\StreamInterface", "Rector\\BetterPhpDocParser\\PhpDocInfo\\PhpDocInfo", "Rector\\BetterPhpDocParser\\PhpDocInfo\\PhpDocInfoFactory", "Rector\\Comments\\NodeDocBlock\\DocBlockUpdater", diff --git a/src/Foundation/Response.php b/src/Foundation/Response.php index 885e0ec..f5ff13a 100644 --- a/src/Foundation/Response.php +++ b/src/Foundation/Response.php @@ -121,39 +121,9 @@ public function body(): string return (string) $this->getBody(); } - /** - * Get the body as a stream. - */ - public function stream(): StreamInterface - { - $stream = $this->getBody(); - - if ($stream->isSeekable()) { - $stream->rewind(); - } - - return $stream; - } - - /** - * Get the body of the response as a PHP resource. - * Useful for storing the file. - * Make sure to close the [guzzle://stream] resource after you have used it. - * - * @throws \InvalidArgumentException - * - * @return resource - */ - public function resource() - { - return StreamWrapper::getResource($this->getBody()); - } - /** * Get the JSON decoded body of the response as an array or scalar value. * - * @noinspection JsonEncodingApiUsageInspection - * * @param null|array-key $key * @param mixed $default * @@ -185,14 +155,26 @@ public function array($key = null, $default = null) /** * Get the JSON decoded body of the response as an object. - * - * @noinspection JsonEncodingApiUsageInspection */ public function object(): ?object { return json_decode($this->body()); } + /** + * Get the JSON decoded body of the response as a collection. + * To use the "collect" method you must install the illuminate/collections package. + * Requires Laravel Collections (composer require illuminate/collections). + * + * @see https://github.com/illuminate/collections + * + * @param null|array-key $key + */ + public function collect($key = null): Collection + { + return Collection::make($this->json($key)); + } + /** * Convert the XML response into a \SimpleXMLElement. * @@ -202,8 +184,6 @@ public function object(): ?object * * @see https://www.php.net/manual/en/book.simplexml.php * - * @noinspection PhpReturnDocTypeMismatchInspection - * * @return false|\SimpleXMLElement */ public function xml(...$arguments) @@ -212,25 +192,39 @@ public function xml(...$arguments) } /** - * Get the JSON decoded body of the response as a collection. - * To use the "collect" method you must install the illuminate/collections package. - * Requires Laravel Collections (composer require illuminate/collections). + * Generate a data URL from the content type and body. + */ + public function dataUrl(): string + { + return \sprintf('data:%s;base64,%s', $this->getHeaderLine('Content-Type'), base64_encode($this->body())); + } + + /** + * Get the body of the response as a PHP resource. + * Useful for storing the file. + * Make sure to close the [guzzle://stream] resource after you have used it. * - * @see https://github.com/illuminate/collections + * @throws \InvalidArgumentException * - * @param null|array-key $key + * @return resource */ - public function collect($key = null): Collection + public function resource() { - return Collection::make($this->json($key)); + return StreamWrapper::getResource($this->getBody()); } /** - * Generate a data URL from the content type and body. + * Get the body as a stream. */ - public function dataUrl(): string + public function stream(): StreamInterface { - return \sprintf('data:%s;base64,%s', $this->getHeaderLine('Content-Type'), base64_encode($this->body())); + $stream = $this->getBody(); + + if ($stream->isSeekable()) { + $stream->rewind(); + } + + return $stream; } /** @@ -238,7 +232,7 @@ public function dataUrl(): string * * @param resource|string $resourceOrPath */ - public function saveAs($resourceOrPath, bool $closeResource = true): void + public function saveAs($resourceOrPath): void { if (!\is_string($resourceOrPath) && !\is_resource($resourceOrPath)) { throw new InvalidArgumentException('The $resourceOrPath argument must be either a file path or a resource.'); @@ -251,18 +245,14 @@ public function saveAs($resourceOrPath, bool $closeResource = true): void } rewind($resource); - $stream = $this->stream(); while (!$stream->eof()) { fwrite($resource, $stream->read(1024)); } - rewind($resource); - - if ($closeResource) { - fclose($resource); - } + // rewind($resource); + fclose($resource); } /** diff --git a/tests/Foundation/ResponseTest.php b/tests/Foundation/ResponseTest.php index 2f5579c..9bd908d 100644 --- a/tests/Foundation/ResponseTest.php +++ b/tests/Foundation/ResponseTest.php @@ -120,28 +120,28 @@ )->toBeInstanceOf(Collection::class); })->group(__DIR__, __FILE__); -it('can convert to resource', function (): void { +it('can convert to data url', function (): void { expect( Response::fromPsrResponse( new \GuzzleHttp\Psr7\Response( 200, - [], - json_encode(['foo' => 'bar'], \JSON_THROW_ON_ERROR), + ['Content-Type' => 'image/png'], + file_get_contents(fixtures_path('image.png')), ), - )->resource(), - )->toBeResource(); + )->dataUrl(), + )->toBe('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyBAMAAADsEZWCAAAAG1BMVEXMzMyWlpaqqqq3t7exsbGcnJy+vr6jo6PFxcUFpPI/AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAQUlEQVQ4jWNgGAWjgP6ASdncAEaiAhaGiACmFhCJLsMaIiDAEQEi0WXYEiMCOCJAJIY9KuYGTC0gknpuHwXDGwAA5fsIZw0iYWYAAAAASUVORK5CYII='); })->group(__DIR__, __FILE__); -it('can convert to data url', function (): void { +it('can convert to resource', function (): void { expect( Response::fromPsrResponse( new \GuzzleHttp\Psr7\Response( 200, - ['Content-Type' => 'image/png'], - file_get_contents(fixtures_path('image.png')), + [], + json_encode(['foo' => 'bar'], \JSON_THROW_ON_ERROR), ), - )->dataUrl(), - )->toBe('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyBAMAAADsEZWCAAAAG1BMVEXMzMyWlpaqqqq3t7exsbGcnJy+vr6jo6PFxcUFpPI/AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAQUlEQVQ4jWNgGAWjgP6ASdncAEaiAhaGiACmFhCJLsMaIiDAEQEi0WXYEiMCOCJAJIY9KuYGTC0gknpuHwXDGwAA5fsIZw0iYWYAAAAASUVORK5CYII='); + )->resource(), + )->toBeResource(); })->group(__DIR__, __FILE__); it('will throw InvalidArgumentException when save to null', function (): void {