create(); $user = User::factory()->create(['tenant_id' => $tenant->id, 'is_active' => true]); $campaign = AdCampaign::create([ 'tenant_id' => $tenant->id, 'name' => 'C', 'audience_days' => 10, 'use_uploaded_list' => false, ]); return [$tenant, $user, $campaign]; } it('на слова Яндекса клиенту уходит письмо и загорается колокольчик', function () { Mail::fake(); [$tenant, $user, $campaign] = notifyCampaign(); app(CampaignMessageService::class)->postFromYandex($campaign, null, 'Изображение не подошло'); Mail::assertQueued(AdModerationMessageMail::class, fn ($mail) => $mail->hasTo($user->email)); expect(InAppNotification::where('tenant_id', $tenant->id)->where('user_id', $user->id)->count())->toBe(1); }); /** * Служебная отметка «документ отправлен в Яндекс» — расписка, а не новость. * Дёргать ею клиента незачем. */ it('на служебную отметку портала письмо не уходит', function () { Mail::fake(); [$tenant, , $campaign] = notifyCampaign(); app(CampaignMessageService::class)->postSystem($campaign, 'Документ отправлен в Яндекс'); Mail::assertNothingQueued(); expect(InAppNotification::where('tenant_id', $tenant->id)->count())->toBe(0); }); /** * Почта — вещь ненадёжная. Если письмо не ушло, сообщение всё равно обязано остаться * в ленте: клиент увидит его, когда зайдёт. Иначе один сбой почты стирает саму новость. */ it('упавшая почта не мешает сообщению лечь в ленту', function () { [, , $campaign] = notifyCampaign(); Mail::shouldReceive('to')->andThrow(new RuntimeException('почта легла')); $message = app(CampaignMessageService::class)->postFromYandex($campaign, null, 'Изображение не подошло'); expect($message)->not->toBeNull() ->and($message->exists)->toBeTrue(); });