forked from GNUsocial/gnu-social
		
	[COMPONENT][Attachment][TESTS] Fix Entity/AttachmentThumbnailTest
This commit is contained in:
		| @@ -224,8 +224,7 @@ class Attachment extends Entity | |||||||
|                     $this->setFilename(null); |                     $this->setFilename(null); | ||||||
|                     $this->setSize(null); |                     $this->setSize(null); | ||||||
|                     // Important not to null neither width nor height |                     // Important not to null neither width nor height | ||||||
|                     DB::persist($this); |                     DB::wrapInTransaction(fn () => DB::persist($this)); | ||||||
|                     DB::flush(); |  | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|                 // @codeCoverageIgnoreStart |                 // @codeCoverageIgnoreStart | ||||||
| @@ -340,7 +339,11 @@ class Attachment extends Entity | |||||||
|      */ |      */ | ||||||
|     public function getThumbnails() |     public function getThumbnails() | ||||||
|     { |     { | ||||||
|         return DB::findBy('attachment_thumbnail', ['attachment_id' => $this->id]); |         return DB::findBy( | ||||||
|  |             AttachmentThumbnail::class, | ||||||
|  |             ['attachment_id' => $this->id], | ||||||
|  |             order_by: ['size' => 'ASC', 'mimetype' => 'ASC'], | ||||||
|  |         ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function getPath() |     public function getPath() | ||||||
| @@ -378,7 +381,7 @@ class Attachment extends Entity | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function getThumbnailUrl(Note|int $note, ?string $size = null) |     public function getThumbnailUrl(Note|int $note, ?string $size = null): string | ||||||
|     { |     { | ||||||
|         return Router::url('note_attachment_thumbnail', ['note_id' => \is_int($note) ? $note : $note->getId(), 'attachment_id' => $this->getId(), 'size' => $size ?? Common::config('thumbnail', 'default_size')]); |         return Router::url('note_attachment_thumbnail', ['note_id' => \is_int($note) ? $note : $note->getId(), 'attachment_id' => $this->getId(), 'size' => $size ?? Common::config('thumbnail', 'default_size')]); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ use App\Core\Event; | |||||||
| use App\Core\GSFile; | use App\Core\GSFile; | ||||||
| use App\Core\Log; | use App\Core\Log; | ||||||
| use App\Core\Router\Router; | use App\Core\Router\Router; | ||||||
|  | use App\Entity\Note; | ||||||
| use App\Util\Common; | use App\Util\Common; | ||||||
| use App\Util\Exception\ClientException; | use App\Util\Exception\ClientException; | ||||||
| use App\Util\Exception\NotFoundException; | use App\Util\Exception\NotFoundException; | ||||||
| @@ -179,7 +180,7 @@ class AttachmentThumbnail extends Entity | |||||||
|         if (isset($this->attachment) && !\is_null($this->attachment)) { |         if (isset($this->attachment) && !\is_null($this->attachment)) { | ||||||
|             return $this->attachment; |             return $this->attachment; | ||||||
|         } else { |         } else { | ||||||
|             return $this->attachment = DB::findOneBy('attachment', ['id' => $this->attachment_id]); |             return $this->attachment = DB::findOneBy(Attachment::class, ['id' => $this->attachment_id]); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -253,14 +254,14 @@ class AttachmentThumbnail extends Entity | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function getPath() |     public function getPath(): string | ||||||
|     { |     { | ||||||
|         return Common::config('thumbnail', 'dir') . \DIRECTORY_SEPARATOR . $this->getFilename(); |         return Common::config('thumbnail', 'dir') . \DIRECTORY_SEPARATOR . $this->getFilename(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function getUrl() |     public function getUrl(Note|int $note): string | ||||||
|     { |     { | ||||||
|         return Router::url('attachment_thumbnail', ['id' => $this->getAttachmentId(), 'size' => self::sizeIntToStr($this->getSize())]); |         return Router::url('note_attachment_thumbnail', ['note_id' => \is_int($note) ? $note : $note->getId(), 'attachment_id' => $this->getAttachmentId(), 'size' => self::sizeIntToStr($this->getSize())]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -277,9 +278,10 @@ class AttachmentThumbnail extends Entity | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         Cache::delete(self::getCacheKey($this->getAttachmentId(), $this->getSize())); |         Cache::delete(self::getCacheKey($this->getAttachmentId(), $this->getSize())); | ||||||
|         DB::remove($this); |  | ||||||
|         if ($flush) { |         if ($flush) { | ||||||
|             DB::flush(); |             DB::wrapInTransaction(fn () => DB::remove($this)); | ||||||
|  |         } else { | ||||||
|  |             DB::remove($this); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,12 +19,13 @@ declare(strict_types = 1); | |||||||
| // along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
 | // along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
| // }}}
 | // }}}
 | ||||||
| 
 | 
 | ||||||
| namespace App\Tests\Entity; | namespace Component\Attachment\tests\Entity; | ||||||
| 
 | 
 | ||||||
| use App\Core\DB\DB; | use App\Core\DB\DB; | ||||||
| use App\Core\Event; | use App\Core\Event; | ||||||
| use App\Util\Exception\NotStoredLocallyException; | use App\Util\Exception\NotStoredLocallyException; | ||||||
| use App\Util\GNUsocialTestCase; | use App\Util\GNUsocialTestCase; | ||||||
|  | use Component\Attachment\Entity\Attachment; | ||||||
| use Component\Attachment\Entity\AttachmentThumbnail; | use Component\Attachment\Entity\AttachmentThumbnail; | ||||||
| use Functional as F; | use Functional as F; | ||||||
| use Jchook\AssertThrows\AssertThrows; | use Jchook\AssertThrows\AssertThrows; | ||||||
| @@ -42,9 +43,9 @@ class AttachmentThumbnailTest extends GNUsocialTestCase | |||||||
|         $file = new SplFileInfo(INSTALLDIR . '/tests/sample-uploads/attachment-lifecycle-target.jpg'); |         $file = new SplFileInfo(INSTALLDIR . '/tests/sample-uploads/attachment-lifecycle-target.jpg'); | ||||||
|         $hash = null; |         $hash = null; | ||||||
|         Event::handle('HashFile', [$file->getPathname(), &$hash]); |         Event::handle('HashFile', [$file->getPathname(), &$hash]); | ||||||
|         $attachment = DB::findOneBy('attachment', ['filehash' => $hash]); |         $attachment = DB::findOneBy(Attachment::class, ['filehash' => $hash]); | ||||||
| 
 | 
 | ||||||
|         $thumbs = [ |         $expected = [ | ||||||
|             AttachmentThumbnail::getOrCreate($attachment, 'small', crop: false), |             AttachmentThumbnail::getOrCreate($attachment, 'small', crop: false), | ||||||
|             AttachmentThumbnail::getOrCreate($attachment, 'medium', crop: false), |             AttachmentThumbnail::getOrCreate($attachment, 'medium', crop: false), | ||||||
|             $thumb = AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false), |             $thumb = AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false), | ||||||
| @@ -54,21 +55,29 @@ class AttachmentThumbnailTest extends GNUsocialTestCase | |||||||
|         $thumb->setAttachment(null); |         $thumb->setAttachment(null); | ||||||
|         static::assertSame($attachment, $thumb->getAttachment()); |         static::assertSame($attachment, $thumb->getAttachment()); | ||||||
| 
 | 
 | ||||||
|         $sort      = fn ($l, $r) => [$l->getWidth(), $l->getHeight()] <=> [$r->getWidth(), $r->getHeight()]; |         $actual = $attachment->getThumbnails(); | ||||||
|         $at_thumbs = F\sort($attachment->getThumbnails(), $sort); |         static::assertSame(\count($expected), \count($actual)); | ||||||
|         static::assertSame($thumbs, $at_thumbs); |         foreach ($expected as $e) { | ||||||
|         array_pop($thumbs); |             $a = array_shift($actual); | ||||||
|         $thumb->delete(flush: true); |             static::assertObjectEquals($e, $a); | ||||||
|         $at_thumbs = F\sort($attachment->getThumbnails(), $sort); |         } | ||||||
|         static::assertSame($thumbs, $at_thumbs); | 
 | ||||||
|  |         array_pop($expected); | ||||||
|  |         $thumb->delete(); | ||||||
|  |         $actual = $attachment->getThumbnails(); | ||||||
|  |         static::assertSame(\count($expected), \count($actual)); | ||||||
|  |         foreach ($expected as $e) { | ||||||
|  |             $a = array_shift($actual); | ||||||
|  |             static::assertObjectEquals($e, $a); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         $attachment->deleteStorage(); |         $attachment->deleteStorage(); | ||||||
| 
 | 
 | ||||||
|         foreach (array_reverse($thumbs) as $t) { |         foreach (array_reverse($attachment->getThumbnails()) as $t) { | ||||||
|             // Since we still have thumbnails, those will be used as the new thumbnail, even though we don't have the original
 |             // 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); |             $new = AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false); | ||||||
|             static::assertSame([$t->getFilename(), $t->getSize()], [$new->getFilename(), $new->getSize()]); |             static::assertSame([$t->getFilename(), $t->getSize()], [$new->getFilename(), $new->getSize()]); | ||||||
|             $t->delete(flush: true); |             $t->delete(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Since the backed storage was deleted and we don't have any more previous thumnbs, we can't generate another thumbnail
 |         // Since the backed storage was deleted and we don't have any more previous thumnbs, we can't generate another thumbnail
 | ||||||
| @@ -159,10 +168,10 @@ class AttachmentThumbnailTest extends GNUsocialTestCase | |||||||
|     public function testGetUrl() |     public function testGetUrl() | ||||||
|     { |     { | ||||||
|         parent::bootKernel(); |         parent::bootKernel(); | ||||||
|         $attachment = DB::findBy('attachment', ['mimetype' => 'image/png'], limit: 1)[0]; |         $attachment = DB::findBy(Attachment::class, ['mimetype' => 'image/png'], limit: 1)[0]; | ||||||
|         $thumb      = AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false); |         $thumb      = AttachmentThumbnail::getOrCreate($attachment, 'big', crop: false); | ||||||
|         $id         = $attachment->getId(); |         $id         = $attachment->getId(); | ||||||
|         $url        = "/attachment/{$id}/thumbnail/big"; |         $expected   = "/object/note/42/attachment/{$id}/thumbnail/big"; | ||||||
|         static::assertSame($url, $thumb->getUrl()); |         static::assertSame($expected, $thumb->getUrl(note: 42)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -52,7 +52,7 @@ class AttachmentCollection extends Entity | |||||||
|     // @codeCoverageIgnoreEnd |     // @codeCoverageIgnoreEnd | ||||||
|     // }}} Autocode |     // }}} Autocode | ||||||
|  |  | ||||||
|     public static function schemaDef() |     public static function schemaDef(): array | ||||||
|     { |     { | ||||||
|         return [ |         return [ | ||||||
|             'name'   => 'attachment_collection', |             'name'   => 'attachment_collection', | ||||||
|   | |||||||
| @@ -63,7 +63,7 @@ class AttachmentCollectionEntry extends Entity | |||||||
|     // @codeCoverageIgnoreEnd |     // @codeCoverageIgnoreEnd | ||||||
|     // }}} Autocode |     // }}} Autocode | ||||||
|  |  | ||||||
|     public static function schemaDef() |     public static function schemaDef(): array | ||||||
|     { |     { | ||||||
|         return [ |         return [ | ||||||
|             'name'   => 'attachment_collection_entry', |             'name'   => 'attachment_collection_entry', | ||||||
|   | |||||||
| @@ -194,7 +194,7 @@ class AttachmentEmbed extends Entity | |||||||
|         return $attr; |         return $attr; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static function schemaDef() |     public static function schemaDef(): array | ||||||
|     { |     { | ||||||
|         return [ |         return [ | ||||||
|             'name'   => 'attachment_embed', |             'name'   => 'attachment_embed', | ||||||
|   | |||||||
| @@ -142,7 +142,7 @@ class NoteFavourite extends Entity | |||||||
|         return array_unique($target_ids); |         return array_unique($target_ids); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static function schemaDef() |     public static function schemaDef(): array | ||||||
|     { |     { | ||||||
|         return [ |         return [ | ||||||
|             'name'   => 'note_favourite', |             'name'   => 'note_favourite', | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ class PinnedNotes extends Entity | |||||||
|         return $this; |         return $this; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static function schemaDef() |     public static function schemaDef(): array | ||||||
|     { |     { | ||||||
|         return [ |         return [ | ||||||
|             'name'   => 'pinned_notes', |             'name'   => 'pinned_notes', | ||||||
|   | |||||||
| @@ -51,7 +51,7 @@ class Wallet extends Entity | |||||||
|     // @codeCoverageIgnoreEnd |     // @codeCoverageIgnoreEnd | ||||||
|     // }}} Autocode |     // }}} Autocode | ||||||
|  |  | ||||||
|     public static function schemaDef() |     public static function schemaDef(): array | ||||||
|     { |     { | ||||||
|         return [ |         return [ | ||||||
|             'name'   => 'webmonetizationWallet', |             'name'   => 'webmonetizationWallet', | ||||||
|   | |||||||
| @@ -90,7 +90,7 @@ class WebMonetization extends Entity | |||||||
|         return $target_ids; |         return $target_ids; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static function schemaDef() |     public static function schemaDef(): array | ||||||
|     { |     { | ||||||
|         return [ |         return [ | ||||||
|             'name'   => 'webmonetization', |             'name'   => 'webmonetization', | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ use App\Util\Exception\NotFoundException; | |||||||
| use App\Util\Formatting; | use App\Util\Formatting; | ||||||
| use BadMethodCallException; | use BadMethodCallException; | ||||||
| use DateTime; | use DateTime; | ||||||
|  | use DateTimeInterface; | ||||||
| use Exception; | use Exception; | ||||||
| use InvalidArgumentException; | use InvalidArgumentException; | ||||||
|  |  | ||||||
| @@ -48,6 +49,8 @@ abstract class Entity | |||||||
|         throw new BadMethodCallException('Non existent method ' . static::class . "::{$name} called with arguments: " . print_r($arguments, true)); |         throw new BadMethodCallException('Non existent method ' . static::class . "::{$name} called with arguments: " . print_r($arguments, true)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     abstract public static function schemaDef(): array; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Create an instance of the called class or fill in the |      * Create an instance of the called class or fill in the | ||||||
|      * properties of $obj with the associative array $args. Doesn't |      * properties of $obj with the associative array $args. Doesn't | ||||||
| @@ -145,6 +148,32 @@ abstract class Entity | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Tests that this object is equal to another one based on a custom object comparison | ||||||
|  |      * | ||||||
|  |      * @param self $other the value to test | ||||||
|  |      * | ||||||
|  |      * @return bool true if equals, false otherwise | ||||||
|  |      */ | ||||||
|  |     public function equals(self $other): bool | ||||||
|  |     { | ||||||
|  |         foreach (array_keys($this::schemaDef()['fields']) as $attribute) { | ||||||
|  |             $getter  = 'get' . Formatting::snakeCaseToPascalCase($attribute); | ||||||
|  |             $current = $this->{$getter}(); | ||||||
|  |             $target  = $other->{$getter}(); | ||||||
|  |             if ($current instanceof DateTimeInterface) { | ||||||
|  |                 if ($current->getTimestamp() !== $target->getTimestamp()) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 if ($current !== $target) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Who should be notified about this object? |      * Who should be notified about this object? | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -332,7 +332,7 @@ class Actor extends Entity | |||||||
|     { |     { | ||||||
|         return Cache::getList( |         return Cache::getList( | ||||||
|             self::cacheKeys($this->getId())['self-tags'], |             self::cacheKeys($this->getId())['self-tags'], | ||||||
|             fn() => DB::findBy(ActorTag::class, ['tagger' => $this->getId(), 'tagged' => $this->getId()], order_by: ['modified' => 'DESC']), |             fn() => DB::findBy(ActorTag::class, ['tagger' => $this->getId(), 'tagged' => $this->getId()], order_by: ['modified' => 'DESC', 'tag' => 'ASC']), | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -153,6 +153,11 @@ abstract class Formatting | |||||||
|         return implode('', F\map(preg_split('/[\b_]/', $str), F\ary('ucfirst', 1))); |         return implode('', F\map(preg_split('/[\b_]/', $str), F\ary('ucfirst', 1))); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public static function snakeCaseToPascalCase(string $str): string | ||||||
|  |     { | ||||||
|  |         return ucfirst(self::snakeCaseToCamelCase($str)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Indent $in, a string or array, $level levels |      * Indent $in, a string or array, $level levels | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -56,10 +56,9 @@ class ActorTest extends GNUsocialTestCase | |||||||
|         ])); |         ])); | ||||||
|         DB::flush(); |         DB::flush(); | ||||||
|         Cache::delete(Actor::cacheKeys($actor->getId())['self-tags']); |         Cache::delete(Actor::cacheKeys($actor->getId())['self-tags']); | ||||||
|         static::assertSame( |         $actual = $actor->getSelfTags(); | ||||||
|             expected: [$actor_tag_foo], |         static::assertCount(1, $actual); | ||||||
|             actual: $actor->getSelfTags(), |         static::assertObjectEquals(expected: $actor_tag_foo, actual: $actual[0]); | ||||||
|         ); |  | ||||||
|         // Add a second self-tag 'foo' |         // Add a second self-tag 'foo' | ||||||
|         $tag = CompTag::sanitize('bar'); |         $tag = CompTag::sanitize('bar'); | ||||||
|         DB::persist($actor_tag_bar = ActorTag::create([ |         DB::persist($actor_tag_bar = ActorTag::create([ | ||||||
| @@ -69,9 +68,14 @@ class ActorTest extends GNUsocialTestCase | |||||||
|         ])); |         ])); | ||||||
|         DB::flush(); |         DB::flush(); | ||||||
|         Cache::delete(Actor::cacheKeys($actor->getId())['self-tags']); |         Cache::delete(Actor::cacheKeys($actor->getId())['self-tags']); | ||||||
|         static::assertSame( |         $actual = $actor->getSelfTags(); | ||||||
|             expected: [$actor_tag_bar, $actor_tag_foo], |         static::assertCount(2, $actual); | ||||||
|             actual: $actor->getSelfTags(), |         foreach ([$actor_tag_bar, $actor_tag_foo] as $expected) { | ||||||
|         ); |             $a = array_shift($actual); | ||||||
|  |             if ($expected->equals($a) !== true) { | ||||||
|  |                 dd($expected, $a); | ||||||
|  |             } | ||||||
|  |             static::assertObjectEquals($expected, $a); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user