diff --git a/app/Actions/CreateStarNotification.php b/app/Actions/CreateStarNotification.php index 0f0d062c4..61afb6032 100644 --- a/app/Actions/CreateStarNotification.php +++ b/app/Actions/CreateStarNotification.php @@ -22,7 +22,7 @@ public function __construct(private ProfileRecipientsQuery $recipients) /** * A star notifies the commit's author, every member of it for an organization's, once while it holds: - * unstarring removes the notification. + * unstarring removes the notification. Nobody hears from people they mute. */ public function handle(User $stargazer, Commit $commit): void { @@ -30,6 +30,7 @@ public function handle(User $stargazer, Commit $commit): void $recipients = DB::query()->fromSub($this->recipients->builder(), 'recipients') ->where('profile_id', $commit->author_id) ->where('user_id', '<>', $stargazer->id) + ->whereNotIn('user_id', $stargazer->mutedBy()->newPivotQuery()->select('muter_id')) ->get(['user_id', 'organization_id']); Notification::query()->insertOrIgnore($recipients->map(fn (object $recipient): array => [ diff --git a/tests/Unit/Actions/CreateStarNotificationTest.php b/tests/Unit/Actions/CreateStarNotificationTest.php index ddfeca976..d69d92c03 100644 --- a/tests/Unit/Actions/CreateStarNotificationTest.php +++ b/tests/Unit/Actions/CreateStarNotificationTest.php @@ -4,7 +4,10 @@ use App\Actions\CreateStarNotification; use App\Enums\NotificationType; +use App\Enums\OrganizationRole; use App\Models\Commit; +use App\Models\Notification; +use App\Models\Organization; use App\Models\User; it('notifies the author of the starred commit', function (): void { @@ -28,6 +31,31 @@ expect($commit->user->notifications()->exists())->toBeFalse(); }); +it('does not notify an author who muted the stargazer', function (): void { + $user = User::factory()->create(); + $commit = Commit::factory()->create(); + + $commit->user->muting()->attach($user); + + resolve(CreateStarNotification::class)->handle($user, $commit); + + expect($commit->user->notifications()->exists())->toBeFalse(); +}); + +it('does not notify the members of an organization who muted the stargazer', function (): void { + $user = User::factory()->create(); + $organization = Organization::factory()->create(); + [$muter, $member] = User::factory()->count(2)->create()->all(); + $organization->members()->attach([$muter->id, $member->id], ['role' => OrganizationRole::Member]); + $commit = Commit::factory()->for($member)->create(['author_id' => $organization->id]); + + $muter->muting()->attach($user); + + resolve(CreateStarNotification::class)->handle($user, $commit); + + expect(Notification::query()->pluck('recipient_id')->all())->toBe([$member->id]); +}); + it('is idempotent', function (): void { $user = User::factory()->create(); $commit = Commit::factory()->create();