| 
									
										
										
										
											2021-08-18 17:32:20 +01:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 09:26:18 +01:00
										 |  |  | declare(strict_types = 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-18 17:32:20 +01:00
										 |  |  | // {{{ License
 | 
					
						
							|  |  |  | // This file is part of GNU social - https://www.gnu.org/software/social
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social 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
 | 
					
						
							|  |  |  | // along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | // }}}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace App\Tests\Entity; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use App\Core\DB\DB; | 
					
						
							|  |  |  | use App\Core\Event; | 
					
						
							|  |  |  | use App\Util\Exception\NotStoredLocallyException; | 
					
						
							|  |  |  | use App\Util\GNUsocialTestCase; | 
					
						
							| 
									
										
										
										
											2021-12-26 09:48:16 +00:00
										 |  |  | use Component\Attachment\Entity\AttachmentThumbnail; | 
					
						
							| 
									
										
										
										
											2021-08-18 17:32:20 +01:00
										 |  |  | use Functional as F; | 
					
						
							|  |  |  | use Jchook\AssertThrows\AssertThrows; | 
					
						
							| 
									
										
										
										
											2021-10-10 09:26:18 +01:00
										 |  |  | use SplFileInfo; | 
					
						
							| 
									
										
										
										
											2021-08-18 17:32:20 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | class AttachmentThumbnailTest extends GNUsocialTestCase | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     use AssertThrows; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testAttachmentThumbnailLifecycle() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         parent::bootKernel(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-19 01:45:11 +01:00
										 |  |  |         // Data fixture already loaded this file, but we need to get its hash to find it
 | 
					
						
							| 
									
										
										
										
											2021-10-10 09:26:18 +01:00
										 |  |  |         $file = new SplFileInfo(INSTALLDIR . '/tests/sample-uploads/attachment-lifecycle-target.jpg'); | 
					
						
							| 
									
										
										
										
											2021-09-06 19:49:03 +01:00
										 |  |  |         $hash = null; | 
					
						
							| 
									
										
										
										
											2021-08-18 17:32:20 +01:00
										 |  |  |         Event::handle('HashFile', [$file->getPathname(), &$hash]); | 
					
						
							|  |  |  |         $attachment = DB::findOneBy('attachment', ['filehash' => $hash]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $thumbs = [ | 
					
						
							| 
									
										
										
										
											2021-09-27 19:47:25 +01:00
										 |  |  |             AttachmentThumbnail::getOrCreate($attachment, 'small', crop: false), | 
					
						
							|  |  |  |             AttachmentThumbnail::getOrCreate($attachment, 'medium', crop: false), | 
					
						
							|  |  |  |             $thumb = AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false), | 
					
						
							| 
									
										
										
										
											2021-08-18 17:32:20 +01:00
										 |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static::assertSame($attachment, $thumb->getAttachment()); | 
					
						
							|  |  |  |         $thumb->setAttachment(null); | 
					
						
							|  |  |  |         static::assertSame($attachment, $thumb->getAttachment()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $sort      = fn ($l, $r) => [$l->getWidth(), $l->getHeight()] <=> [$r->getWidth(), $r->getHeight()]; | 
					
						
							|  |  |  |         $at_thumbs = F\sort($attachment->getThumbnails(), $sort); | 
					
						
							|  |  |  |         static::assertSame($thumbs, $at_thumbs); | 
					
						
							|  |  |  |         array_pop($thumbs); | 
					
						
							|  |  |  |         $thumb->delete(flush: true); | 
					
						
							|  |  |  |         $at_thumbs = F\sort($attachment->getThumbnails(), $sort); | 
					
						
							|  |  |  |         static::assertSame($thumbs, $at_thumbs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $attachment->deleteStorage(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-15 19:27:39 +00:00
										 |  |  |         foreach (array_reverse($thumbs) as $t) { | 
					
						
							|  |  |  |             // Since we still have thumbnails, those will be used as the new thumbnail, even though we don't have the original
 | 
					
						
							|  |  |  |             $new = AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false); | 
					
						
							|  |  |  |             static::assertSame([$t->getFilename(), $t->getSize()], [$new->getFilename(), $new->getSize()]); | 
					
						
							|  |  |  |             $t->delete(flush: true); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Since the backed storage was deleted and we don't have any more previous thumnbs, we can't generate another thumbnail
 | 
					
						
							| 
									
										
										
										
											2021-09-27 19:47:25 +01:00
										 |  |  |         static::assertThrows(NotStoredLocallyException::class, fn () => AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false)); | 
					
						
							| 
									
										
										
										
											2021-08-18 17:32:20 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $attachment->kill(); | 
					
						
							| 
									
										
										
										
											2021-11-15 19:27:39 +00:00
										 |  |  |         // static::assertThrows(NotStoredLocallyException::class, fn () => AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false));
 | 
					
						
							| 
									
										
										
										
											2021-08-18 17:32:20 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-19 19:14:37 +01:00
										 |  |  |     public function testInvalidThumbnail() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         parent::bootKernel(); | 
					
						
							| 
									
										
										
										
											2021-10-10 09:26:18 +01:00
										 |  |  |         $file = new SplFileInfo(INSTALLDIR . '/tests/sample-uploads/spreadsheet.ods'); | 
					
						
							| 
									
										
										
										
											2021-09-06 19:49:03 +01:00
										 |  |  |         $hash = null; | 
					
						
							| 
									
										
										
										
											2021-08-19 19:14:37 +01:00
										 |  |  |         Event::handle('HashFile', [$file->getPathname(), &$hash]); | 
					
						
							|  |  |  |         $attachment = DB::findOneBy('attachment', ['filehash' => $hash]); | 
					
						
							| 
									
										
										
										
											2021-11-15 19:27:39 +00:00
										 |  |  |         static::assertNull(AttachmentThumbnail::getOrCreate($attachment, 'small', crop: false)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-19 19:14:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-15 19:27:39 +00:00
										 |  |  |     public function testPredictScalingValues() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         parent::bootKernel(); | 
					
						
							|  |  |  |         // TODO test with cropping
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $inputs = [ | 
					
						
							|  |  |  |             [100, 100], | 
					
						
							|  |  |  |             [400, 200], | 
					
						
							|  |  |  |             [800, 400], | 
					
						
							|  |  |  |             [1600, 800], | 
					
						
							|  |  |  |             [1600, 1600], | 
					
						
							|  |  |  |             // 16:9 video
 | 
					
						
							|  |  |  |             [854,  480], | 
					
						
							|  |  |  |             [1280, 720], | 
					
						
							|  |  |  |             [1920, 1080], | 
					
						
							|  |  |  |             [2560, 1440], | 
					
						
							|  |  |  |             [3840, 2160], | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $outputs = [ | 
					
						
							|  |  |  |             'small' => [ | 
					
						
							|  |  |  |                 [100, 100], | 
					
						
							|  |  |  |                 [400, 200], | 
					
						
							|  |  |  |                 [32, 14], | 
					
						
							|  |  |  |                 [32, 14], | 
					
						
							|  |  |  |                 [32, 32], | 
					
						
							|  |  |  |                 // 16:9 video
 | 
					
						
							|  |  |  |                 [32, 21], | 
					
						
							|  |  |  |                 [32, 21], | 
					
						
							|  |  |  |                 [32, 21], | 
					
						
							|  |  |  |                 [32, 21], | 
					
						
							|  |  |  |                 [32, 21], | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             'medium' => [ | 
					
						
							|  |  |  |                 [100, 100], | 
					
						
							|  |  |  |                 [400, 200], | 
					
						
							|  |  |  |                 [256, 116], | 
					
						
							|  |  |  |                 [256, 116], | 
					
						
							|  |  |  |                 [256, 256], | 
					
						
							|  |  |  |                 // 16:9 video
 | 
					
						
							|  |  |  |                 [256, 170], | 
					
						
							|  |  |  |                 [256, 170], | 
					
						
							|  |  |  |                 [256, 170], | 
					
						
							|  |  |  |                 [256, 170], | 
					
						
							|  |  |  |                 [256, 170], | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             'big' => [ | 
					
						
							|  |  |  |                 [100, 100], | 
					
						
							|  |  |  |                 [400, 200], | 
					
						
							|  |  |  |                 [496, 225], | 
					
						
							|  |  |  |                 [496, 225], | 
					
						
							|  |  |  |                 [496, 496], | 
					
						
							|  |  |  |                 // 16:9 video
 | 
					
						
							|  |  |  |                 [496, 330], | 
					
						
							|  |  |  |                 [496, 330], | 
					
						
							|  |  |  |                 [496, 330], | 
					
						
							|  |  |  |                 [496, 330], | 
					
						
							|  |  |  |                 [496, 330], | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach (['small', 'medium', 'big'] as $size) { | 
					
						
							|  |  |  |             foreach (F\zip($inputs, $outputs[$size]) as [$existing, $results]) { | 
					
						
							|  |  |  |                 static::assertSame($results, AttachmentThumbnail::predictScalingValues(existing_width: $existing[0], existing_height: $existing[1], requested_size: $size, crop: false)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-08-19 19:14:37 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-15 19:27:39 +00:00
										 |  |  |     public function testGetUrl() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         parent::bootKernel(); | 
					
						
							|  |  |  |         $attachment = DB::findBy('attachment', ['mimetype' => 'image/png'], limit: 1)[0]; | 
					
						
							|  |  |  |         $thumb      = AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false); | 
					
						
							|  |  |  |         $id         = $attachment->getId(); | 
					
						
							|  |  |  |         $url        = "/attachment/{$id}/thumbnail/big"; | 
					
						
							|  |  |  |         static::assertSame($url, $thumb->getUrl()); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-18 17:32:20 +01:00
										 |  |  | } |