Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/ImageResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,38 @@

final readonly class ImageResult
{
/**
* @param float|null $psnr Peak signal-to-noise ratio in decibels between the
* input and the output, returned by optimize and convert.
* Higher means closer to the input. Null when the API
* does not send the field (resize, thumbnail) or when
* the loss cannot be measured.
*/
public function __construct(
public string $bytes,
public string $format,
public string $mimeType,
public int $size,
public int $width,
public int $height,
public ?float $psnr = null,
) {}

/**
* @param array<string, mixed> $data
*/
public static function fromResponse(array $data): self
{
$psnr = data_get($data, 'psnr');

return new self(
bytes: (string) base64_decode((string) data_get($data, 'output.data'), true),
format: (string) data_get($data, 'format'),
mimeType: (string) data_get($data, 'mime_type'),
size: (int) data_get($data, 'size'),
width: (int) data_get($data, 'width'),
height: (int) data_get($data, 'height'),
psnr: $psnr === null ? null : (float) $psnr,
);
}
}
33 changes: 31 additions & 2 deletions tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use MathiasGrimm\GlimpsePhp\ForbiddenException;
use MathiasGrimm\GlimpsePhp\ImageFormat;
use MathiasGrimm\GlimpsePhp\ImageInfo;
use MathiasGrimm\GlimpsePhp\ImageResult;
use MathiasGrimm\GlimpsePhp\RateLimitException;
use MathiasGrimm\GlimpsePhp\SizeEstimate;
use MathiasGrimm\GlimpsePhp\Tests\Fixtures\Images;
Expand All @@ -30,15 +31,16 @@ function client(Factory $http, Closure|string|null $token = 'test-token', string
}

test('convert posts the base64 envelope and returns a decoded ImageResult', function () {
$http = fakeHttp(['*/v1/convert' => Factory::response(fakeTransformResponse())]);
$http = fakeHttp(['*/v1/convert' => Factory::response(fakeTransformResponse(overrides: ['psnr' => 41.27]))]);

$result = client($http)->convert(Images::png(), ImageFormat::Jpg);

expect($result->bytes)->toBe(Images::jpg())
->and($result->format)->toBe(ImageFormat::Jpg->value)
->and($result->mimeType)->toBe('image/jpeg')
->and($result->width)->toBe(1280)
->and($result->height)->toBe(720);
->and($result->height)->toBe(720)
->and($result->psnr)->toBe(41.27);

$http->assertSent(function (Request $request) {
return $request->url() === 'https://glimpseimg.com/api/v1/convert'
Expand All @@ -49,6 +51,33 @@ function client(Factory $http, Closure|string|null $token = 'test-token', string
});
});

test('a null psnr in the response stays null', function () {
$http = fakeHttp(['*/v1/optimize' => Factory::response(fakeTransformResponse(overrides: ['psnr' => null]))]);

expect(client($http)->optimize(Images::png())->psnr)->toBeNull();
});

test('a response without a psnr field maps to a null psnr', function () {
// Resize and thumbnail responses do not carry the field at all.
$http = fakeHttp(['*/v1/resize' => Factory::response(fakeTransformResponse())]);

expect(client($http)->resize(Images::png(), width: 800)->psnr)->toBeNull();
});

test('an integer psnr in the response is cast to float', function () {
$http = fakeHttp(['*/v1/optimize' => Factory::response(fakeTransformResponse(overrides: ['psnr' => 42]))]);

expect(client($http)->optimize(Images::png())->psnr)->toBe(42.0);
});

test('the six-argument constructor stays valid and defaults psnr to null', function () {
// Locks backward compatibility: callers built against pre-3.1 must keep
// working without passing psnr.
$result = new ImageResult('bytes', 'jpg', 'image/jpeg', 100, 20, 10);

expect($result->psnr)->toBeNull();
});

test('convert sends optimize and quality when given', function () {
$http = fakeHttp(['*/v1/convert' => Factory::response(fakeTransformResponse())]);

Expand Down
5 changes: 3 additions & 2 deletions tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,12 @@ function fakeInfoResponse(array $overrides = []): array
/**
* A canned successful transform-endpoint response envelope.
*
* @param array<string, mixed> $overrides
* @return array{data: array<string, mixed>}
*/
function fakeTransformResponse(string $format = 'jpg', string $mimeType = 'image/jpeg'): array
function fakeTransformResponse(string $format = 'jpg', string $mimeType = 'image/jpeg', array $overrides = []): array
{
return ['data' => [
return ['data' => $overrides + [
'output' => ['type' => 'BASE64', 'data' => Images::JPG_BASE64],
'format' => $format,
'mime_type' => $mimeType,
Expand Down
Loading