From 799683229a4e1c39b3d01864c64a4818099a97ec Mon Sep 17 00:00:00 2001 From: ildyria Date: Sun, 4 Jan 2026 21:26:33 +0100 Subject: [PATCH 1/3] fix propagation not happening --- app/Actions/Photo/Pipes/Shared/Save.php | 3 -- app/Actions/Photo/Pipes/Shared/SetParent.php | 5 ++++ tests/ImageProcessing/Photo/PhotoAddTest.php | 31 ++++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/app/Actions/Photo/Pipes/Shared/Save.php b/app/Actions/Photo/Pipes/Shared/Save.php index 60ad890b486..1d66e4ae398 100644 --- a/app/Actions/Photo/Pipes/Shared/Save.php +++ b/app/Actions/Photo/Pipes/Shared/Save.php @@ -22,9 +22,6 @@ public function handle(PhotoDTO $state, \Closure $next): PhotoDTO $state->getPhoto()->save(); $state->getPhoto()->tags()->sync($state->getTags()->pluck('id')->all()); - // Dispatch event for album stats recomputation - PhotoSaved::dispatch($state->getPhoto()->id); - return $next($state); } } \ No newline at end of file diff --git a/app/Actions/Photo/Pipes/Shared/SetParent.php b/app/Actions/Photo/Pipes/Shared/SetParent.php index 8517b5ed535..c7dbaa9e634 100644 --- a/app/Actions/Photo/Pipes/Shared/SetParent.php +++ b/app/Actions/Photo/Pipes/Shared/SetParent.php @@ -12,6 +12,7 @@ use App\Contracts\PhotoCreate\SharedPipe; use App\DTO\PhotoCreate\DuplicateDTO; use App\DTO\PhotoCreate\StandaloneDTO; +use App\Events\PhotoSaved; use App\Exceptions\Internal\LycheeLogicException; use App\Models\Album; use Illuminate\Support\Facades\DB; @@ -46,6 +47,10 @@ public function handle(DuplicateDTO|StandaloneDTO $state, \Closure $next): Dupli $state->photo->load('albums'); } + // Dispatch event for album stats recomputation + // This must be done after SetParent so the photo_album relationship exists + PhotoSaved::dispatch($state->photo->id); + return $next($state); } } \ No newline at end of file diff --git a/tests/ImageProcessing/Photo/PhotoAddTest.php b/tests/ImageProcessing/Photo/PhotoAddTest.php index af24d17465f..d25b505a24e 100644 --- a/tests/ImageProcessing/Photo/PhotoAddTest.php +++ b/tests/ImageProcessing/Photo/PhotoAddTest.php @@ -18,6 +18,9 @@ namespace Tests\ImageProcessing\Photo; +use App\Jobs\RecomputeAlbumSizeJob; +use App\Jobs\RecomputeAlbumStatsJob; +use Illuminate\Support\Facades\Queue; use Tests\Constants\TestConstants; use Tests\Feature_v2\Base\BaseApiWithDataTest; @@ -159,4 +162,32 @@ public function testGoogleMotionPicture(): void $response = $this->deleteJson('Photo', ['photo_ids' => [$id], 'from_id' => 'unsorted']); $this->assertNoContent($response); } + + public function testPhotoUploadDispatchesJobs(): void + { + // Fake only the recompute jobs, not the ProcessImageJob + // This allows the photo upload to complete while capturing the recompute job dispatches + Queue::fake([ + RecomputeAlbumStatsJob::class, + RecomputeAlbumSizeJob::class, + ]); + + $this->catchFailureSilence = []; + + // Upload a photo to an album + $response = $this->actingAs($this->admin)->upload('Photo', filename: TestConstants::SAMPLE_FILE_NIGHT_IMAGE, album_id: $this->album1->id); + $this->assertCreated($response); + + // Assert that RecomputeAlbumStatsJob was dispatched for the album + Queue::assertPushed(RecomputeAlbumStatsJob::class, function (RecomputeAlbumStatsJob $job) { + return $job->album_id === $this->album1->id; + }); + + // Assert that RecomputeAlbumSizeJob was dispatched for the album + Queue::assertPushed(RecomputeAlbumSizeJob::class, function (RecomputeAlbumSizeJob $job) { + return $job->album_id === $this->album1->id; + }); + + $this->catchFailureSilence = ["App\Exceptions\MediaFileOperationException"]; + } } From 9824fb6fa1ff6c21817ed2e82e397c2e4d3ac1df Mon Sep 17 00:00:00 2001 From: ildyria Date: Sun, 4 Jan 2026 21:27:27 +0100 Subject: [PATCH 2/3] formatting --- app/Actions/Photo/Pipes/Shared/Save.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Actions/Photo/Pipes/Shared/Save.php b/app/Actions/Photo/Pipes/Shared/Save.php index 1d66e4ae398..0a54d9be587 100644 --- a/app/Actions/Photo/Pipes/Shared/Save.php +++ b/app/Actions/Photo/Pipes/Shared/Save.php @@ -10,7 +10,6 @@ use App\Contracts\PhotoCreate\PhotoDTO; use App\Contracts\PhotoCreate\PhotoPipe; -use App\Events\PhotoSaved; /** * Persist current Photo object into database. From 7eaa955b25aab63da9e4e202e00e1c4e6f3e8d00 Mon Sep 17 00:00:00 2001 From: ildyria Date: Sun, 4 Jan 2026 22:17:30 +0100 Subject: [PATCH 3/3] WRTC --- app/Actions/Photo/Pipes/Shared/SetParent.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Actions/Photo/Pipes/Shared/SetParent.php b/app/Actions/Photo/Pipes/Shared/SetParent.php index c7dbaa9e634..f13bd63859c 100644 --- a/app/Actions/Photo/Pipes/Shared/SetParent.php +++ b/app/Actions/Photo/Pipes/Shared/SetParent.php @@ -45,11 +45,11 @@ public function handle(DuplicateDTO|StandaloneDTO $state, \Closure $next): Dupli // Avoid unnecessary DB request, when we access the album of a // photo later (e.g. when a notification is sent). $state->photo->load('albums'); - } - // Dispatch event for album stats recomputation - // This must be done after SetParent so the photo_album relationship exists - PhotoSaved::dispatch($state->photo->id); + // Dispatch event for album stats recomputation + // This must be done after SetParent so the photo_album relationship exists + PhotoSaved::dispatch($state->photo->id); + } return $next($state); }