Skip to content

Commit

Permalink
test(Response): Refactor saveAs method and add new test case
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
guanguans committed Nov 15, 2024
1 parent e3ded5b commit 82055ed
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 61 deletions.
1 change: 1 addition & 0 deletions composer-require-checker.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
92 changes: 41 additions & 51 deletions src/Foundation/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down Expand Up @@ -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.
*
Expand All @@ -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)
Expand All @@ -212,33 +192,47 @@ 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;
}

/**
* Save the response to resource or file.
*
* @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.');
Expand All @@ -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);
}

/**
Expand Down
20 changes: 10 additions & 10 deletions tests/Foundation/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 82055ed

Please sign in to comment.