generated from Nodarx/template
1bf71898db
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
129 lines
6.0 KiB
PHP
129 lines
6.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
use KTXC\Context\TenantContextInterface;
|
|
use KTXC\Resource\ProviderManager;
|
|
use KTXF\Preview\PreviewGenerationException;
|
|
use KTXF\Preview\PreviewRequest;
|
|
use KTXF\Preview\PreviewSource;
|
|
use KTXF\Resource\BinaryResource;
|
|
use KTXF\Resource\Provider\ProviderInterface;
|
|
use KTXM\ProviderPreviewImageMagick\Provider as ImageProvider;
|
|
use KTXM\ServiceWopi\Host\Configuration;
|
|
use KTXM\ServiceWopi\Host\WopiService;
|
|
use KTXM\ServiceWopi\Module;
|
|
use KTXM\ServiceWopi\Preview\ConversionClient;
|
|
use KTXM\ServiceWopi\Preview\Provider;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class PreviewTest extends TestCase
|
|
{
|
|
public function testRegistersPreviewProvider(): void
|
|
{
|
|
$registry = $this->createMock(ProviderManager::class);
|
|
$registry->expects(self::once())->method('register')->with(ProviderInterface::TYPE_PREVIEW, 'wopi', Provider::class);
|
|
(new Module($registry))->boot();
|
|
}
|
|
|
|
public function testSupportedFormatsAndOutputs(): void
|
|
{
|
|
$provider = $this->provider($this->createStub(ConversionClient::class));
|
|
foreach (WopiService::FORMATS as $mime) {
|
|
self::assertTrue($provider->supports($mime, $this->request()));
|
|
}
|
|
self::assertFalse($provider->supports('application/pdf', $this->request()));
|
|
self::assertFalse($provider->supports('invalid', $this->request()));
|
|
self::assertFalse($provider->supports(WopiService::FORMATS['docx'], new PreviewRequest(100, 100, 'application/pdf', 80)));
|
|
}
|
|
|
|
public function testDisabledWopiDoesNotOfferPreviews(): void
|
|
{
|
|
$tenant = $this->createStub(TenantContextInterface::class);
|
|
$tenant->method('requireIdentifier')->willReturn('tenant');
|
|
$wopi = $this->createStub(WopiService::class);
|
|
$wopi->method('configuration')->willThrowException(new \KTXM\ServiceWopi\Host\HostException('Disabled', 503));
|
|
$provider = new Provider($tenant, $wopi, $this->createStub(ConversionClient::class), new ImageProvider());
|
|
self::assertFalse($provider->supports(WopiService::FORMATS['docx'], $this->request()));
|
|
}
|
|
|
|
public function testRejectsStreamExceedingTenantLimitBeforeUpload(): void
|
|
{
|
|
$client = $this->createMock(ConversionClient::class);
|
|
$client->expects(self::never())->method('pdf');
|
|
$this->expectException(PreviewGenerationException::class);
|
|
$this->provider($client, 3)->generate($this->source('oversized'), $this->request());
|
|
}
|
|
|
|
public function testConversionFailurePropagatesForManagerFallback(): void
|
|
{
|
|
$client = $this->createMock(ConversionClient::class);
|
|
$client->expects(self::once())->method('pdf')->willThrowException(new PreviewGenerationException('Unavailable'));
|
|
$this->expectException(PreviewGenerationException::class);
|
|
$this->provider($client)->generate($this->source('document'), $this->request());
|
|
}
|
|
|
|
public function testRendersOnlyFirstPageAndResizesToRequestedOutput(): void
|
|
{
|
|
// Two differently shaped, colored pages make selecting the wrong page observable.
|
|
$pdf = new Imagick();
|
|
foreach ([[400, 200, 'red'], [200, 400, 'blue']] as [$width, $height, $color]) {
|
|
$page = new Imagick();
|
|
$page->newImage($width, $height, 'transparent', 'pdf');
|
|
$drawing = new ImagickDraw();
|
|
$drawing->setFillColor($color);
|
|
$drawing->rectangle($width * 0.15, $height * 0.2, $width * 0.75, $height * 0.8);
|
|
$page->drawImage($drawing);
|
|
$drawing->clear();
|
|
$pdf->addImage($page);
|
|
$page->clear();
|
|
}
|
|
$bytes = $pdf->getImagesBlob();
|
|
$pdf->clear();
|
|
$client = $this->createMock(ConversionClient::class);
|
|
$client->expects(self::once())->method('pdf')->with(
|
|
self::callback(fn ($server) => $server->url === 'https://office.test'),
|
|
'document', 'docx', WopiService::FORMATS['docx'],
|
|
)->willReturn($bytes);
|
|
$result = $this->provider($client)->generate($this->source('document'), $this->request());
|
|
self::assertSame(100, $result->width);
|
|
self::assertSame(50, $result->height);
|
|
self::assertSame('image/webp', $result->resource->mimeType());
|
|
$output = implode('', iterator_to_array($result->resource->stream()));
|
|
$image = new Imagick();
|
|
$image->readImageBlob($output);
|
|
$color = $image->getImagePixelColor(20, 20)->getColor();
|
|
self::assertGreaterThan(200, $color['r']);
|
|
self::assertLessThan(30, $color['b']);
|
|
$paper = $image->getImagePixelColor(5, 5)->getColor();
|
|
self::assertGreaterThan(245, $paper['r']);
|
|
self::assertGreaterThan(245, $paper['g']);
|
|
self::assertGreaterThan(245, $paper['b']);
|
|
self::assertSame(1.0, $image->getImagePixelColor(5, 5)->getColorValue(Imagick::COLOR_ALPHA));
|
|
$edge = $image->getImagePixelColor(0, 25)->getColor();
|
|
self::assertLessThan(230, $edge['r']);
|
|
self::assertGreaterThan(130, $edge['r']);
|
|
$image->clear();
|
|
}
|
|
|
|
private function provider(ConversionClient $client, int $limit = 1048576): Provider
|
|
{
|
|
$tenant = $this->createStub(TenantContextInterface::class);
|
|
$tenant->method('requireIdentifier')->willReturn('tenant');
|
|
$wopi = $this->createStub(WopiService::class);
|
|
$wopi->method('configuration')->willReturn(new Configuration([
|
|
'enabled' => true, 'office_server' => 'https://office.test',
|
|
'origin_server' => 'https://app.test', 'max_bytes' => $limit,
|
|
]));
|
|
return new Provider($tenant, $wopi, $client, new ImageProvider());
|
|
}
|
|
|
|
private function request(): PreviewRequest { return new PreviewRequest(100, 100, 'image/webp', 80); }
|
|
|
|
private function source(string $content): PreviewSource
|
|
{
|
|
return new PreviewSource('document', 'file', 'version', WopiService::FORMATS['docx'], null,
|
|
static fn () => new BinaryResource('file.docx', WopiService::FORMATS['docx'],
|
|
(static function () use ($content): Generator { yield $content; })()));
|
|
}
|
|
}
|