AttachmentThumbnailTest.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. declare(strict_types = 1);
  3. // {{{ License
  4. // This file is part of GNU social - https://www.gnu.org/software/social
  5. //
  6. // GNU social is free software: you can redistribute it and/or modify
  7. // it under the terms of the GNU Affero General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // GNU social is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU Affero General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU Affero General Public License
  17. // along with GNU social. If not, see <http://www.gnu.org/licenses/>.
  18. // }}}
  19. namespace App\Tests\Entity;
  20. use App\Core\DB\DB;
  21. use App\Core\Event;
  22. use App\Util\Exception\NotStoredLocallyException;
  23. use App\Util\GNUsocialTestCase;
  24. use Component\Attachment\Entity\AttachmentThumbnail;
  25. use Functional as F;
  26. use Jchook\AssertThrows\AssertThrows;
  27. use SplFileInfo;
  28. class AttachmentThumbnailTest extends GNUsocialTestCase
  29. {
  30. use AssertThrows;
  31. public function testAttachmentThumbnailLifecycle()
  32. {
  33. parent::bootKernel();
  34. // Data fixture already loaded this file, but we need to get its hash to find it
  35. $file = new SplFileInfo(INSTALLDIR . '/tests/sample-uploads/attachment-lifecycle-target.jpg');
  36. $hash = null;
  37. Event::handle('HashFile', [$file->getPathname(), &$hash]);
  38. $attachment = DB::findOneBy('attachment', ['filehash' => $hash]);
  39. $thumbs = [
  40. AttachmentThumbnail::getOrCreate($attachment, 'small', crop: false),
  41. AttachmentThumbnail::getOrCreate($attachment, 'medium', crop: false),
  42. $thumb = AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false),
  43. ];
  44. static::assertSame($attachment, $thumb->getAttachment());
  45. $thumb->setAttachment(null);
  46. static::assertSame($attachment, $thumb->getAttachment());
  47. $sort = fn ($l, $r) => [$l->getWidth(), $l->getHeight()] <=> [$r->getWidth(), $r->getHeight()];
  48. $at_thumbs = F\sort($attachment->getThumbnails(), $sort);
  49. static::assertSame($thumbs, $at_thumbs);
  50. array_pop($thumbs);
  51. $thumb->delete(flush: true);
  52. $at_thumbs = F\sort($attachment->getThumbnails(), $sort);
  53. static::assertSame($thumbs, $at_thumbs);
  54. $attachment->deleteStorage();
  55. foreach (array_reverse($thumbs) as $t) {
  56. // Since we still have thumbnails, those will be used as the new thumbnail, even though we don't have the original
  57. $new = AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false);
  58. static::assertSame([$t->getFilename(), $t->getSize()], [$new->getFilename(), $new->getSize()]);
  59. $t->delete(flush: true);
  60. }
  61. // Since the backed storage was deleted and we don't have any more previous thumnbs, we can't generate another thumbnail
  62. static::assertThrows(NotStoredLocallyException::class, fn () => AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false));
  63. $attachment->kill();
  64. // static::assertThrows(NotStoredLocallyException::class, fn () => AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false));
  65. }
  66. public function testInvalidThumbnail()
  67. {
  68. parent::bootKernel();
  69. $file = new SplFileInfo(INSTALLDIR . '/tests/sample-uploads/spreadsheet.ods');
  70. $hash = null;
  71. Event::handle('HashFile', [$file->getPathname(), &$hash]);
  72. $attachment = DB::findOneBy('attachment', ['filehash' => $hash]);
  73. static::assertNull(AttachmentThumbnail::getOrCreate($attachment, 'small', crop: false));
  74. }
  75. public function testPredictScalingValues()
  76. {
  77. parent::bootKernel();
  78. // TODO test with cropping
  79. $inputs = [
  80. [100, 100],
  81. [400, 200],
  82. [800, 400],
  83. [1600, 800],
  84. [1600, 1600],
  85. // 16:9 video
  86. [854, 480],
  87. [1280, 720],
  88. [1920, 1080],
  89. [2560, 1440],
  90. [3840, 2160],
  91. ];
  92. $outputs = [
  93. 'small' => [
  94. [100, 100],
  95. [400, 200],
  96. [32, 14],
  97. [32, 14],
  98. [32, 32],
  99. // 16:9 video
  100. [32, 21],
  101. [32, 21],
  102. [32, 21],
  103. [32, 21],
  104. [32, 21],
  105. ],
  106. 'medium' => [
  107. [100, 100],
  108. [400, 200],
  109. [256, 116],
  110. [256, 116],
  111. [256, 256],
  112. // 16:9 video
  113. [256, 170],
  114. [256, 170],
  115. [256, 170],
  116. [256, 170],
  117. [256, 170],
  118. ],
  119. 'big' => [
  120. [100, 100],
  121. [400, 200],
  122. [496, 225],
  123. [496, 225],
  124. [496, 496],
  125. // 16:9 video
  126. [496, 330],
  127. [496, 330],
  128. [496, 330],
  129. [496, 330],
  130. [496, 330],
  131. ],
  132. ];
  133. foreach (['small', 'medium', 'big'] as $size) {
  134. foreach (F\zip($inputs, $outputs[$size]) as [$existing, $results]) {
  135. static::assertSame($results, AttachmentThumbnail::predictScalingValues(existing_width: $existing[0], existing_height: $existing[1], requested_size: $size, crop: false));
  136. }
  137. }
  138. }
  139. public function testGetUrl()
  140. {
  141. parent::bootKernel();
  142. $attachment = DB::findBy('attachment', ['mimetype' => 'image/png'], limit: 1)[0];
  143. $thumb = AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false);
  144. $id = $attachment->getId();
  145. $url = "/attachment/{$id}/thumbnail/big";
  146. static::assertSame($url, $thumb->getUrl());
  147. }
  148. }