aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/Preview/GeneratorTest.php
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/Preview/GeneratorTest.php')
-rw-r--r--tests/lib/Preview/GeneratorTest.php464
1 files changed, 464 insertions, 0 deletions
diff --git a/tests/lib/Preview/GeneratorTest.php b/tests/lib/Preview/GeneratorTest.php
new file mode 100644
index 00000000000..edf5418da6e
--- /dev/null
+++ b/tests/lib/Preview/GeneratorTest.php
@@ -0,0 +1,464 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Preview;
+
+use OC\Preview\Generator;
+use OC\Preview\GeneratorHelper;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\File;
+use OCP\Files\IAppData;
+use OCP\Files\NotFoundException;
+use OCP\Files\SimpleFS\ISimpleFile;
+use OCP\Files\SimpleFS\ISimpleFolder;
+use OCP\IConfig;
+use OCP\IImage;
+use OCP\IPreview;
+use OCP\Preview\BeforePreviewFetchedEvent;
+use OCP\Preview\IProviderV2;
+use Psr\Log\LoggerInterface;
+
+class GeneratorTest extends \Test\TestCase {
+ /** @var IConfig&\PHPUnit\Framework\MockObject\MockObject */
+ private $config;
+
+ /** @var IPreview&\PHPUnit\Framework\MockObject\MockObject */
+ private $previewManager;
+
+ /** @var IAppData&\PHPUnit\Framework\MockObject\MockObject */
+ private $appData;
+
+ /** @var GeneratorHelper&\PHPUnit\Framework\MockObject\MockObject */
+ private $helper;
+
+ /** @var IEventDispatcher&\PHPUnit\Framework\MockObject\MockObject */
+ private $eventDispatcher;
+
+ /** @var Generator */
+ private $generator;
+
+ private LoggerInterface&\PHPUnit\Framework\MockObject\MockObject $logger;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->config = $this->createMock(IConfig::class);
+ $this->previewManager = $this->createMock(IPreview::class);
+ $this->appData = $this->createMock(IAppData::class);
+ $this->helper = $this->createMock(GeneratorHelper::class);
+ $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
+ $this->logger = $this->createMock(LoggerInterface::class);
+
+ $this->generator = new Generator(
+ $this->config,
+ $this->previewManager,
+ $this->appData,
+ $this->helper,
+ $this->eventDispatcher,
+ $this->logger,
+ );
+ }
+
+ public function testGetCachedPreview(): void {
+ $file = $this->createMock(File::class);
+ $file->method('isReadable')
+ ->willReturn(true);
+ $file->method('getMimeType')
+ ->willReturn('myMimeType');
+ $file->method('getId')
+ ->willReturn(42);
+
+ $this->previewManager->method('isMimeSupported')
+ ->with($this->equalTo('myMimeType'))
+ ->willReturn(true);
+
+ $previewFolder = $this->createMock(ISimpleFolder::class);
+ $this->appData->method('getFolder')
+ ->with($this->equalTo(42))
+ ->willReturn($previewFolder);
+
+ $maxPreview = $this->createMock(ISimpleFile::class);
+ $maxPreview->method('getName')
+ ->willReturn('1000-1000-max.png');
+ $maxPreview->method('getSize')->willReturn(1000);
+ $maxPreview->method('getMimeType')
+ ->willReturn('image/png');
+
+ $previewFile = $this->createMock(ISimpleFile::class);
+ $previewFile->method('getSize')->willReturn(1000);
+ $previewFile->method('getName')->willReturn('256-256.png');
+
+ $previewFolder->method('getDirectoryListing')
+ ->willReturn([$maxPreview, $previewFile]);
+
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatchTyped')
+ ->with(new BeforePreviewFetchedEvent($file, 100, 100, false, IPreview::MODE_FILL, null));
+
+ $result = $this->generator->getPreview($file, 100, 100);
+ $this->assertSame($previewFile, $result);
+ }
+
+ public function testGetNewPreview(): void {
+ $file = $this->createMock(File::class);
+ $file->method('isReadable')
+ ->willReturn(true);
+ $file->method('getMimeType')
+ ->willReturn('myMimeType');
+ $file->method('getId')
+ ->willReturn(42);
+
+ $this->previewManager->method('isMimeSupported')
+ ->with($this->equalTo('myMimeType'))
+ ->willReturn(true);
+
+ $previewFolder = $this->createMock(ISimpleFolder::class);
+ $this->appData->method('getFolder')
+ ->with($this->equalTo(42))
+ ->willThrowException(new NotFoundException());
+
+ $this->appData->method('newFolder')
+ ->with($this->equalTo(42))
+ ->willReturn($previewFolder);
+
+ $this->config->method('getSystemValue')
+ ->willReturnCallback(function ($key, $default) {
+ return $default;
+ });
+
+ $this->config->method('getSystemValueInt')
+ ->willReturnCallback(function ($key, $default) {
+ return $default;
+ });
+
+ $invalidProvider = $this->createMock(IProviderV2::class);
+ $invalidProvider->method('isAvailable')
+ ->willReturn(true);
+ $unavailableProvider = $this->createMock(IProviderV2::class);
+ $unavailableProvider->method('isAvailable')
+ ->willReturn(false);
+ $validProvider = $this->createMock(IProviderV2::class);
+ $validProvider->method('isAvailable')
+ ->with($file)
+ ->willReturn(true);
+
+ $this->previewManager->method('getProviders')
+ ->willReturn([
+ '/image\/png/' => ['wrongProvider'],
+ '/myMimeType/' => ['brokenProvider', 'invalidProvider', 'unavailableProvider', 'validProvider'],
+ ]);
+
+ $this->helper->method('getProvider')
+ ->willReturnCallback(function ($provider) use ($invalidProvider, $validProvider, $unavailableProvider) {
+ if ($provider === 'wrongProvider') {
+ $this->fail('Wrongprovider should not be constructed!');
+ } elseif ($provider === 'brokenProvider') {
+ return false;
+ } elseif ($provider === 'invalidProvider') {
+ return $invalidProvider;
+ } elseif ($provider === 'validProvider') {
+ return $validProvider;
+ } elseif ($provider === 'unavailableProvider') {
+ return $unavailableProvider;
+ }
+ $this->fail('Unexpected provider requested');
+ });
+
+ $image = $this->createMock(IImage::class);
+ $image->method('width')->willReturn(2048);
+ $image->method('height')->willReturn(2048);
+ $image->method('valid')->willReturn(true);
+ $image->method('dataMimeType')->willReturn('image/png');
+
+ $this->helper->method('getThumbnail')
+ ->willReturnCallback(function ($provider, $file, $x, $y) use ($invalidProvider, $validProvider, $image) {
+ if ($provider === $validProvider) {
+ return $image;
+ } else {
+ return false;
+ }
+ });
+
+ $image->method('data')
+ ->willReturn('my data');
+
+ $maxPreview = $this->createMock(ISimpleFile::class);
+ $maxPreview->method('getName')->willReturn('2048-2048-max.png');
+ $maxPreview->method('getMimeType')->willReturn('image/png');
+ $maxPreview->method('getSize')->willReturn(1000);
+
+ $previewFile = $this->createMock(ISimpleFile::class);
+ $previewFile->method('getSize')->willReturn(1000);
+
+ $previewFolder->method('getDirectoryListing')
+ ->willReturn([]);
+ $previewFolder->method('newFile')
+ ->willReturnMap([
+ ['2048-2048-max.png', 'my data', $maxPreview],
+ ['256-256.png', 'my resized data', $previewFile],
+ ]);
+
+ $previewFolder->method('getFile')
+ ->with($this->equalTo('256-256.png'))
+ ->willThrowException(new NotFoundException());
+
+ $image = $this->getMockImage(2048, 2048, 'my resized data');
+ $this->helper->method('getImage')
+ ->with($this->equalTo($maxPreview))
+ ->willReturn($image);
+
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatchTyped')
+ ->with(new BeforePreviewFetchedEvent($file, 100, 100, false, IPreview::MODE_FILL, null));
+
+ $result = $this->generator->getPreview($file, 100, 100);
+ $this->assertSame($previewFile, $result);
+ }
+
+ public function testInvalidMimeType(): void {
+ $this->expectException(NotFoundException::class);
+
+ $file = $this->createMock(File::class);
+ $file->method('isReadable')
+ ->willReturn(true);
+ $file->method('getId')
+ ->willReturn(42);
+
+ $this->previewManager->method('isMimeSupported')
+ ->with('invalidType')
+ ->willReturn(false);
+
+ $previewFolder = $this->createMock(ISimpleFolder::class);
+ $this->appData->method('getFolder')
+ ->with($this->equalTo(42))
+ ->willReturn($previewFolder);
+
+ $maxPreview = $this->createMock(ISimpleFile::class);
+ $maxPreview->method('getName')
+ ->willReturn('2048-2048-max.png');
+ $maxPreview->method('getMimeType')
+ ->willReturn('image/png');
+
+ $previewFolder->method('getDirectoryListing')
+ ->willReturn([$maxPreview]);
+
+ $previewFolder->method('getFile')
+ ->with($this->equalTo('1024-512-crop.png'))
+ ->willThrowException(new NotFoundException());
+
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatchTyped')
+ ->with(new BeforePreviewFetchedEvent($file, 1024, 512, true, IPreview::MODE_COVER, 'invalidType'));
+
+ $this->generator->getPreview($file, 1024, 512, true, IPreview::MODE_COVER, 'invalidType');
+ }
+
+ public function testReturnCachedPreviewsWithoutCheckingSupportedMimetype(): void {
+ $file = $this->createMock(File::class);
+ $file->method('isReadable')
+ ->willReturn(true);
+ $file->method('getId')
+ ->willReturn(42);
+
+
+ $previewFolder = $this->createMock(ISimpleFolder::class);
+ $this->appData->method('getFolder')
+ ->with($this->equalTo(42))
+ ->willReturn($previewFolder);
+
+ $maxPreview = $this->createMock(ISimpleFile::class);
+ $maxPreview->method('getName')
+ ->willReturn('2048-2048-max.png');
+ $maxPreview->method('getSize')->willReturn(1000);
+ $maxPreview->method('getMimeType')
+ ->willReturn('image/png');
+
+ $preview = $this->createMock(ISimpleFile::class);
+ $preview->method('getSize')->willReturn(1000);
+ $preview->method('getName')->willReturn('1024-512-crop.png');
+
+ $previewFolder->method('getDirectoryListing')
+ ->willReturn([$maxPreview, $preview]);
+
+ $this->previewManager->expects($this->never())
+ ->method('isMimeSupported');
+
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatchTyped')
+ ->with(new BeforePreviewFetchedEvent($file, 1024, 512, true, IPreview::MODE_COVER, 'invalidType'));
+
+ $result = $this->generator->getPreview($file, 1024, 512, true, IPreview::MODE_COVER, 'invalidType');
+ $this->assertSame($preview, $result);
+ }
+
+ public function testNoProvider(): void {
+ $file = $this->createMock(File::class);
+ $file->method('isReadable')
+ ->willReturn(true);
+ $file->method('getMimeType')
+ ->willReturn('myMimeType');
+ $file->method('getId')
+ ->willReturn(42);
+
+ $previewFolder = $this->createMock(ISimpleFolder::class);
+ $this->appData->method('getFolder')
+ ->with($this->equalTo(42))
+ ->willReturn($previewFolder);
+
+ $previewFolder->method('getDirectoryListing')
+ ->willReturn([]);
+
+ $this->previewManager->method('getProviders')
+ ->willReturn([]);
+
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatchTyped')
+ ->with(new BeforePreviewFetchedEvent($file, 100, 100, false, IPreview::MODE_FILL, null));
+
+ $this->expectException(NotFoundException::class);
+ $this->generator->getPreview($file, 100, 100);
+ }
+
+ private function getMockImage($width, $height, $data = null) {
+ $image = $this->createMock(IImage::class);
+ $image->method('height')->willReturn($width);
+ $image->method('width')->willReturn($height);
+ $image->method('valid')->willReturn(true);
+ $image->method('dataMimeType')->willReturn('image/png');
+ $image->method('data')->willReturn($data);
+
+ $image->method('resizeCopy')->willReturnCallback(function ($size) use ($data) {
+ return $this->getMockImage($size, $size, $data);
+ });
+ $image->method('preciseResizeCopy')->willReturnCallback(function ($width, $height) use ($data) {
+ return $this->getMockImage($width, $height, $data);
+ });
+ $image->method('cropCopy')->willReturnCallback(function ($x, $y, $width, $height) use ($data) {
+ return $this->getMockImage($width, $height, $data);
+ });
+
+ return $image;
+ }
+
+ public static function dataSize(): array {
+ return [
+ [1024, 2048, 512, 512, false, IPreview::MODE_FILL, 256, 512],
+ [1024, 2048, 512, 512, false, IPreview::MODE_COVER, 512, 1024],
+ [1024, 2048, 512, 512, true, IPreview::MODE_FILL, 1024, 1024],
+ [1024, 2048, 512, 512, true, IPreview::MODE_COVER, 1024, 1024],
+
+ [1024, 2048, -1, 512, false, IPreview::MODE_COVER, 256, 512],
+ [1024, 2048, 512, -1, false, IPreview::MODE_FILL, 512, 1024],
+
+ [1024, 2048, 250, 1100, true, IPreview::MODE_COVER, 256, 1126],
+ [1024, 1100, 250, 1100, true, IPreview::MODE_COVER, 250, 1100],
+
+ [1024, 2048, 4096, 2048, false, IPreview::MODE_FILL, 1024, 2048],
+ [1024, 2048, 4096, 2048, false, IPreview::MODE_COVER, 1024, 2048],
+
+
+ [2048, 1024, 512, 512, false, IPreview::MODE_FILL, 512, 256],
+ [2048, 1024, 512, 512, false, IPreview::MODE_COVER, 1024, 512],
+ [2048, 1024, 512, 512, true, IPreview::MODE_FILL, 1024, 1024],
+ [2048, 1024, 512, 512, true, IPreview::MODE_COVER, 1024, 1024],
+
+ [2048, 1024, -1, 512, false, IPreview::MODE_FILL, 1024, 512],
+ [2048, 1024, 512, -1, false, IPreview::MODE_COVER, 512, 256],
+
+ [2048, 1024, 4096, 1024, true, IPreview::MODE_FILL, 2048, 512],
+ [2048, 1024, 4096, 1024, true, IPreview::MODE_COVER, 2048, 512],
+
+ //Test minimum size
+ [2048, 1024, 32, 32, false, IPreview::MODE_FILL, 64, 32],
+ [2048, 1024, 32, 32, false, IPreview::MODE_COVER, 64, 32],
+ [2048, 1024, 32, 32, true, IPreview::MODE_FILL, 64, 64],
+ [2048, 1024, 32, 32, true, IPreview::MODE_COVER, 64, 64],
+ ];
+ }
+
+ /**
+ *
+ * @param int $maxX
+ * @param int $maxY
+ * @param int $reqX
+ * @param int $reqY
+ * @param bool $crop
+ * @param string $mode
+ * @param int $expectedX
+ * @param int $expectedY
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataSize')]
+ public function testCorrectSize($maxX, $maxY, $reqX, $reqY, $crop, $mode, $expectedX, $expectedY): void {
+ $file = $this->createMock(File::class);
+ $file->method('isReadable')
+ ->willReturn(true);
+ $file->method('getMimeType')
+ ->willReturn('myMimeType');
+ $file->method('getId')
+ ->willReturn(42);
+
+ $this->previewManager->method('isMimeSupported')
+ ->with($this->equalTo('myMimeType'))
+ ->willReturn(true);
+
+ $previewFolder = $this->createMock(ISimpleFolder::class);
+ $this->appData->method('getFolder')
+ ->with($this->equalTo(42))
+ ->willReturn($previewFolder);
+
+ $maxPreview = $this->createMock(ISimpleFile::class);
+ $maxPreview->method('getName')
+ ->willReturn($maxX . '-' . $maxY . '-max.png');
+ $maxPreview->method('getMimeType')
+ ->willReturn('image/png');
+ $maxPreview->method('getSize')->willReturn(1000);
+
+ $previewFolder->method('getDirectoryListing')
+ ->willReturn([$maxPreview]);
+
+ $filename = $expectedX . '-' . $expectedY;
+ if ($crop) {
+ $filename .= '-crop';
+ }
+ $filename .= '.png';
+ $previewFolder->method('getFile')
+ ->with($this->equalTo($filename))
+ ->willThrowException(new NotFoundException());
+
+ $image = $this->getMockImage($maxX, $maxY);
+ $this->helper->method('getImage')
+ ->with($this->equalTo($maxPreview))
+ ->willReturn($image);
+
+ $preview = $this->createMock(ISimpleFile::class);
+ $preview->method('getSize')->willReturn(1000);
+ $previewFolder->method('newFile')
+ ->with($this->equalTo($filename))
+ ->willReturn($preview);
+
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatchTyped')
+ ->with(new BeforePreviewFetchedEvent($file, $reqX, $reqY, $crop, $mode, null));
+
+ $result = $this->generator->getPreview($file, $reqX, $reqY, $crop, $mode);
+ if ($expectedX === $maxX && $expectedY === $maxY) {
+ $this->assertSame($maxPreview, $result);
+ } else {
+ $this->assertSame($preview, $result);
+ }
+ }
+
+ public function testUnreadbleFile(): void {
+ $file = $this->createMock(File::class);
+ $file->method('isReadable')
+ ->willReturn(false);
+
+ $this->expectException(NotFoundException::class);
+
+ $this->generator->getPreview($file, 100, 100, false);
+ }
+}