Files
portal/app/tests/Feature/ClientSms/MigrationRerunTest.php
T

61 lines
2.7 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use Illuminate\Foundation\Testing\RefreshDatabase;
/**
* Миграции модуля должны выдерживать ПОВТОРНЫЙ запуск (журнал В-73).
*
* Зачем это вообще нужно. Обычно повторный запуск невозможен: Laravel помнит,
* какие файлы уже применены. Но на боевом кластере миграции накатываются иначе —
* SQL вынимается командой `migrate --pretend` и подаётся в базу руками одной
* транзакцией. Там памяти «этот файл уже применён» нет: повторный накат того же
* куска — после сорвавшегося выката, после отката на середине — упирается в
* «таблица уже существует» и валит всю транзакцию целиком.
*
* Тест прогоняет `up()` каждой миграции модуля ВТОРОЙ раз — сразу после того, как
* её уже применил RefreshDatabase. Ничего не должно сломаться и ничего не должно
* измениться. Проверяется вырезанием: убери защиту в любой миграции — тест краснеет
* с именем этой миграции.
*/
uses(RefreshDatabase::class);
/** Миграции клиентского СМС-модуля — по маске имени, чтобы новые попадали сюда сами. */
function clientSmsMigrationFiles(): array
{
$all = glob(database_path('migrations/*.php')) ?: [];
$mine = array_values(array_filter(
$all,
fn (string $path) => str_contains(basename($path), 'client_sms')
|| str_contains(basename($path), 'sms_global_optouts'),
));
// Модуль продаж (`sales_sms`) — чужая работа, сюда не берём.
return array_values(array_filter(
$mine,
fn (string $path) => ! str_contains(basename($path), 'sales_sms'),
));
}
it('все миграции модуля переживают повторный запуск', function () {
$files = clientSmsMigrationFiles();
expect($files)->not->toBeEmpty();
foreach ($files as $path) {
$migration = require $path;
try {
$migration->up();
} catch (Throwable $e) {
$this->fail(sprintf(
"Миграция %s не переживает повторный запуск:\n%s",
basename($path),
$e->getMessage(),
));
}
}
});