a5c278adaf
Прогон рекламной папки оставлял в базе 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>
69 lines
2.7 KiB
PHP
69 lines
2.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\Tenant;
|
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
// Откат после теста. Без него записи файла остаются в базе и роняют ЧУЖИЕ тесты:
|
|
// 01.08.2026 девятнадцать чужих проводок уронили денежную проверку приёмника МТС.
|
|
uses(DatabaseTransactions::class);
|
|
|
|
it('creates ad_campaign_ads and ad_campaign_phones rows scoped to tenant and campaign', function () {
|
|
$tenant = Tenant::factory()->create();
|
|
|
|
$campaignId = DB::table('ad_campaigns')->insertGetId([
|
|
'tenant_id' => $tenant->id,
|
|
'channel' => 'yandex',
|
|
'name' => 'Кампания №1',
|
|
'status' => 'draft',
|
|
'audience_days' => 10,
|
|
'use_uploaded_list' => false,
|
|
'weekly_budget_rub' => '2500.00',
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
DB::table('ad_campaign_ads')->insert([
|
|
'tenant_id' => $tenant->id,
|
|
'campaign_id' => $campaignId,
|
|
'title' => 'Заголовок объявления',
|
|
'title2' => 'Второй заголовок',
|
|
'text' => 'Текст объявления с описанием услуги',
|
|
'href' => 'https://liderra.ru/promo',
|
|
'image_normal_hash' => null,
|
|
'image_wide_hash' => null,
|
|
'yandex_ad_id' => null,
|
|
'moderation_status' => 'draft',
|
|
'moderation_reason' => null,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
DB::table('ad_campaign_phones')->insert([
|
|
'tenant_id' => $tenant->id,
|
|
'campaign_id' => $campaignId,
|
|
'phone' => '79990000001',
|
|
'expires_at' => null,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
expect(DB::table('ad_campaign_ads')->where('campaign_id', $campaignId)->count())->toBe(1)
|
|
->and(DB::table('ad_campaign_phones')->where('campaign_id', $campaignId)->count())->toBe(1);
|
|
|
|
$ad = DB::table('ad_campaign_ads')->where('campaign_id', $campaignId)->first();
|
|
expect($ad->tenant_id)->toBe($tenant->id)
|
|
->and($ad->title)->toBe('Заголовок объявления')
|
|
->and($ad->title2)->toBe('Второй заголовок')
|
|
->and($ad->text)->toBe('Текст объявления с описанием услуги')
|
|
->and($ad->href)->toBe('https://liderra.ru/promo')
|
|
->and($ad->moderation_status)->toBe('draft');
|
|
|
|
$phone = DB::table('ad_campaign_phones')->where('campaign_id', $campaignId)->first();
|
|
expect($phone->tenant_id)->toBe($tenant->id)
|
|
->and($phone->phone)->toBe('79990000001')
|
|
->and($phone->expires_at)->toBeNull();
|
|
});
|