Files
portal/app/tests/Feature/Advertising/CampaignMessageNotifyTest.php
T
Дмитрий a5c278adaf test: рекламная папка и журнал вебхука перестали оставлять записи — остаток 44 → 0
Прогон рекламной папки оставлял в базе 44 записи. Теперь ноль, папка целиком
зелёная — 351 из 351. Полная tests/Feature: 3282 теста, 0 падений, и после неё
в базе не остаётся НИЧЕГО, кроме справочников, которые кладутся при сборке.

Два места прошлая смена считала неизлечимыми — оба вылечились, потому что
диагноз был не перепроверен:

  1. CampaignBannerEndpointsTest оставлял 24 записи, больше половины всей грязи.
     Он нарочно ловит отказ базы, а после отказа внутри транзакции Postgres
     глушит все следующие команды. Лечение — ловить отказ в ОТДЕЛЬНОЙ точке
     сохранения: DB::transaction внутри уже открытой ставит savepoint и
     откатывает только его. Приёмка вырезанием: убрал уникальный ключ в
     миграции — тест покраснел ровно там, где должен; вернул — зелёный.

  2. AdWalletUnderRealRoleTest. В промте: «откат противопоказан, он ходит
     настоящей ролью базы». Оказалось — не противопоказан, смена роли идёт по
     ТОМУ ЖЕ соединению и незакоммиченные записи видны. Тут была реальная
     опасность, что откат обезвредит самого сторожа, поэтому вырезание делал
     отдельно: убрал у службы установку контекста клиента — оба теста
     покраснели. Значит сторож сторожит по-прежнему.

Журнал вебхука оставлял 4 строки: он пишется ВТОРЫМ соединением к базе, куда
обычный откат не дотягивается. Двум файлам добавлена общая связка соединений
(SharesSupplierPdo) — папка вебхука теперь оставляет ноль.

Прежняя оценка исправлена. В промте стояло «~20 файлов оставляют по одной-две
записи». На деле после уборки восьми главных грязь оставляли ДВА файла из всей
папки: 2 и 3 записи, сумма сошлась с наблюдаемыми 5 ровно. «Нет отката» и
«гадит в базу» — разные вещи: папка Autopodbor, где без отката 16 файлов, не
оставляет ни одной записи. Мерить надо остатком, а не поиском по тексту.

Боевой код не тронут: git diff по app/app/ пуст после каждой правки.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 01:15:44 +03:00

70 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
use App\Mail\AdModerationMessageMail;
use App\Models\AdCampaign;
use App\Models\InAppNotification;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Advertising\CampaignMessageService;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Mail;
// Откат после теста. Без него записи файла остаются в базе и роняют ЧУЖИЕ тесты:
// 01.08.2026 девятнадцать чужих проводок уронили денежную проверку приёмника МТС.
uses(DatabaseTransactions::class);
function notifyCampaign(): array
{
$tenant = Tenant::factory()->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();
});