diff options
author | Olivier Paroz <github@oparoz.com> | 2015-06-06 16:21:36 +0200 |
---|---|---|
committer | Olivier Paroz <github@oparoz.com> | 2015-06-06 16:25:04 +0200 |
commit | 71d65cb713ebfb85ee19f9f3cd17dd915360fe9b (patch) | |
tree | 7281b8a32d148d27ae375dd1c45308416e63eee7 /tests/lib/preview | |
parent | 16708ae1873ddd563c3177b87cf7a4c395dca609 (diff) | |
download | nextcloud-server-71d65cb713ebfb85ee19f9f3cd17dd915360fe9b.tar.gz nextcloud-server-71d65cb713ebfb85ee19f9f3cd17dd915360fe9b.zip |
Fix max preview, some resizing and caching issues and force preview providers to resize their previews properly
* introduces a method in OC_Image which doesn't stretch images when trying to make them fit in a box
* adds the method to all key providers so that they can do their job, as expected by the Preview class
* improves the caching mechanism of Preview in order to reduce I/O and to avoid filling the available disk space
* fixes some long standing issues
* **contains mostly tests**
Diffstat (limited to 'tests/lib/preview')
-rw-r--r-- | tests/lib/preview/bitmap.php | 36 | ||||
-rw-r--r-- | tests/lib/preview/image.php | 36 | ||||
-rw-r--r-- | tests/lib/preview/movie.php | 46 | ||||
-rw-r--r-- | tests/lib/preview/mp3.php | 36 | ||||
-rw-r--r-- | tests/lib/preview/office.php | 43 | ||||
-rw-r--r-- | tests/lib/preview/provider.php | 187 | ||||
-rw-r--r-- | tests/lib/preview/svg.php | 41 | ||||
-rw-r--r-- | tests/lib/preview/txt.php | 37 |
8 files changed, 462 insertions, 0 deletions
diff --git a/tests/lib/preview/bitmap.php b/tests/lib/preview/bitmap.php new file mode 100644 index 00000000000..49112852e29 --- /dev/null +++ b/tests/lib/preview/bitmap.php @@ -0,0 +1,36 @@ +<?php +/** + * @author Olivier Paroz <owncloud@interfasys.ch> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace Test\Preview; + +class Bitmap extends Provider { + + public function setUp() { + parent::setUp(); + + $fileName = 'testimage.eps'; + $this->imgPath = $this->prepareTestFile($fileName, \OC::$SERVERROOT . '/tests/data/' . $fileName); + $this->width = 2400; + $this->height = 1707; + $this->provider = new \OC\Preview\Postscript; + } + +} diff --git a/tests/lib/preview/image.php b/tests/lib/preview/image.php new file mode 100644 index 00000000000..af46f4e4a66 --- /dev/null +++ b/tests/lib/preview/image.php @@ -0,0 +1,36 @@ +<?php +/** + * @author Olivier Paroz <owncloud@interfasys.ch> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace Test\Preview; + +class Image extends Provider { + + public function setUp() { + parent::setUp(); + + $fileName = 'testimage.jpg'; + $this->imgPath = $this->prepareTestFile($fileName, \OC::$SERVERROOT . '/tests/data/' . $fileName); + $this->width = 1680; + $this->height = 1050; + $this->provider = new \OC\Preview\JPEG(); + } + +} diff --git a/tests/lib/preview/movie.php b/tests/lib/preview/movie.php new file mode 100644 index 00000000000..c6b0c0f7322 --- /dev/null +++ b/tests/lib/preview/movie.php @@ -0,0 +1,46 @@ +<?php +/** + * @author Olivier Paroz <owncloud@interfasys.ch> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace Test\Preview; + +class Movie extends Provider { + + public function setUp() { + $avconvBinary = \OC_Helper::findBinaryPath('avconv'); + $ffmpegBinary = ($avconvBinary) ? null : \OC_Helper::findBinaryPath('ffmpeg'); + + if ($avconvBinary || $ffmpegBinary) { + parent::setUp(); + + \OC\Preview\Movie::$avconvBinary = $avconvBinary; + \OC\Preview\Movie::$ffmpegBinary = $ffmpegBinary; + + $fileName = 'testimage.mp4'; + $this->imgPath = $this->prepareTestFile($fileName, \OC::$SERVERROOT . '/tests/data/' . $fileName); + $this->width = 560; + $this->height = 320; + $this->provider = new \OC\Preview\Movie; + } else { + $this->markTestSkipped('No Movie provider present'); + } + } + +} diff --git a/tests/lib/preview/mp3.php b/tests/lib/preview/mp3.php new file mode 100644 index 00000000000..ac3ab07a2bd --- /dev/null +++ b/tests/lib/preview/mp3.php @@ -0,0 +1,36 @@ +<?php +/** + * @author Olivier Paroz <owncloud@interfasys.ch> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace Test\Preview; + +class MP3 extends Provider { + + public function setUp() { + parent::setUp(); + + $fileName = 'testimage.mp3'; + $this->imgPath = $this->prepareTestFile($fileName, \OC::$SERVERROOT . '/tests/data/' . $fileName); + $this->width = 200; + $this->height = 200; + $this->provider = new \OC\Preview\MP3; + } + +} diff --git a/tests/lib/preview/office.php b/tests/lib/preview/office.php new file mode 100644 index 00000000000..22eeb0aed33 --- /dev/null +++ b/tests/lib/preview/office.php @@ -0,0 +1,43 @@ +<?php +/** + * @author Olivier Paroz <owncloud@interfasys.ch> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace Test\Preview; + +class Office extends Provider { + + public function setUp() { + $libreofficeBinary = \OC_Helper::findBinaryPath('libreoffice'); + $openofficeBinary = ($libreofficeBinary) ? null : \OC_Helper::findBinaryPath('openoffice'); + + if ($libreofficeBinary || $openofficeBinary) { + parent::setUp(); + + $fileName = 'testimage.odt'; + $this->imgPath = $this->prepareTestFile($fileName, \OC::$SERVERROOT . '/tests/data/' . $fileName); + $this->width = 595; + $this->height = 842; + $this->provider = new \OC\Preview\OpenDocument; + } else { + $this->markTestSkipped('No Office provider present'); + } + } + +} diff --git a/tests/lib/preview/provider.php b/tests/lib/preview/provider.php new file mode 100644 index 00000000000..62b5dde5ec6 --- /dev/null +++ b/tests/lib/preview/provider.php @@ -0,0 +1,187 @@ +<?php +/** + * @author Olivier Paroz <owncloud@interfasys.ch> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace Test\Preview; + +abstract class Provider extends \Test\TestCase { + + /** @var string */ + protected $imgPath; + /** @var int */ + protected $width; + /** @var int */ + protected $height; + /** @var \OC\Preview\Provider */ + protected $provider; + /** @var int */ + protected $maxWidth = 1024; + /** @var int */ + protected $maxHeight = 1024; + /** @var bool */ + protected $scalingUp = false; + /** @var int */ + protected $userId; + /** @var \OC\Files\View */ + protected $rootView; + /** @var \OC\Files\Storage\Storage */ + protected $storage; + + protected function setUp() { + parent::setUp(); + + $userManager = \OC::$server->getUserManager(); + $userManager->clearBackends(); + $backend = new \OC_User_Dummy(); + $userManager->registerBackend($backend); + + $userId = $this->getUniqueID(); + $backend->createUser($userId, $userId); + $this->loginAsUser($userId); + + $this->storage = new \OC\Files\Storage\Temporary([]); + \OC\Files\Filesystem::mount($this->storage, [], '/' . $userId . '/'); + + $this->rootView = new \OC\Files\View(''); + $this->rootView->mkdir('/' . $userId); + $this->rootView->mkdir('/' . $userId . '/files'); + + $this->userId = $userId; + } + + protected function tearDown() { + $this->logout(); + + parent::tearDown(); + } + + public static function dimensionsDataProvider() { + return [ + [-rand(5, 100), -rand(5, 100)], + [rand(5, 100), rand(5, 100)], + [-rand(5, 100), rand(5, 100)], + [rand(5, 100), -rand(5, 100)], + ]; + } + + /** + * Launches all the tests we have + * + * @dataProvider dimensionsDataProvider + * + * @param int $widthAdjustment + * @param int $heightAdjustment + */ + public function testGetThumbnail($widthAdjustment, $heightAdjustment) { + $ratio = round($this->width / $this->height, 2); + $this->maxWidth = $this->width - $widthAdjustment; + $this->maxHeight = $this->height - $heightAdjustment; + + // Testing code + /*print_r("w $this->width "); + print_r("h $this->height "); + print_r("r $ratio ");*/ + + $preview = $this->getPreview($this->provider); + // The TXT provider uses the max dimensions to create its canvas, + // so the ratio will always be the one of the max dimension canvas + if (!$this->provider instanceof \OC\Preview\TXT) { + $this->doesRatioMatch($preview, $ratio); + } + $this->doesPreviewFit($preview); + } + + /** + * Adds the test file to the filesystem + * + * @param string $fileName name of the file to create + * @param string $fileContent path to file to use for test + * + * @return string + */ + protected function prepareTestFile($fileName, $fileContent) { + $imgData = file_get_contents($fileContent); + $imgPath = '/' . $this->userId . '/files/' . $fileName; + $this->rootView->file_put_contents($imgPath, $imgData); + + $scanner = $this->storage->getScanner(); + $scanner->scan(''); + + return $imgPath; + } + + /** + * Retrieves a max size thumbnail can be created + * + * @param \OC\Preview\Provider $provider + * + * @return bool|\OCP\IImage + */ + private function getPreview($provider) { + $preview = $provider->getThumbnail($this->imgPath, $this->maxWidth, $this->maxHeight, $this->scalingUp, $this->rootView); + + $this->assertNotEquals(false, $preview); + $this->assertEquals(true, $preview->valid()); + + return $preview; + } + + /** + * Checks if the preview ratio matches the original ratio + * + * @param \OCP\IImage $preview + * @param int $ratio + */ + private function doesRatioMatch($preview, $ratio) { + $previewRatio = round($preview->width() / $preview->height(), 2); + $this->assertEquals($ratio, $previewRatio); + } + + /** + * Tests if a max size preview of smaller dimensions can be created + * + * @param \OCP\IImage $preview + */ + private function doesPreviewFit($preview) { + $maxDimRatio = round($this->maxWidth / $this->maxHeight, 2); + $previewRatio = round($preview->width() / $preview->height(), 2); + + // Testing code + /*print_r("mw $this->maxWidth "); + print_r("mh $this->maxHeight "); + print_r("mr $maxDimRatio "); + $pw = $preview->width(); + $ph = $preview->height(); + print_r("pw $pw "); + print_r("ph $ph "); + print_r("pr $previewRatio ");*/ + + if ($maxDimRatio < $previewRatio) { + $this->assertLessThanOrEqual($this->maxWidth, $preview->width()); + $this->assertLessThan($this->maxHeight, $preview->height()); + } elseif ($maxDimRatio > $previewRatio) { + $this->assertLessThan($this->maxWidth, $preview->width()); + $this->assertLessThanOrEqual($this->maxHeight, $preview->height()); + } else { // Original had to be resized + $this->assertLessThanOrEqual($this->maxWidth, $preview->width()); + $this->assertLessThanOrEqual($this->maxHeight, $preview->height()); + } + } +} diff --git a/tests/lib/preview/svg.php b/tests/lib/preview/svg.php new file mode 100644 index 00000000000..768569c72ed --- /dev/null +++ b/tests/lib/preview/svg.php @@ -0,0 +1,41 @@ +<?php +/** + * @author Olivier Paroz <owncloud@interfasys.ch> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace Test\Preview; + +class SVG extends Provider { + + public function setUp() { + $checkImagick = new \Imagick(); + if (count($checkImagick->queryFormats('SVG')) === 1) { + parent::setUp(); + + $fileName = 'testimagelarge.svg'; + $this->imgPath = $this->prepareTestFile($fileName, \OC::$SERVERROOT . '/tests/data/' . $fileName); + $this->width = 3000; + $this->height = 2000; + $this->provider = new \OC\Preview\SVG; + } else { + $this->markTestSkipped('No SVG provider present'); + } + } + +} diff --git a/tests/lib/preview/txt.php b/tests/lib/preview/txt.php new file mode 100644 index 00000000000..8bda86f25e3 --- /dev/null +++ b/tests/lib/preview/txt.php @@ -0,0 +1,37 @@ +<?php +/** + * @author Olivier Paroz <owncloud@interfasys.ch> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace Test\Preview; + +class TXT extends Provider { + + public function setUp() { + parent::setUp(); + + $fileName = 'lorem-big.txt'; + $this->imgPath = $this->prepareTestFile($fileName, \OC::$SERVERROOT . '/tests/data/' . $fileName); + // Arbitrary width and length which won't be used to calculate the ratio + $this->width = 500; + $this->height = 200; + $this->provider = new \OC\Preview\TXT; + } + +} |