37a8a5c17f
FN-3: онбординг-confirm не ставил users.email_verified_at — поле вне fillable, mass-assign его гасил. RegistrationService::confirm теперь forceFill is_active + email_verified_at. TDD ConfirmSetsEmailVerifiedAtTest. FN-2: миграция 2026_06_19_130000 дропнула таблицу reminders, но забыла ALTER COLUMN notification_preferences SET DEFAULT — реальный DB-дефолт оставался с мёртвым ключом reminder, расходясь с каноном schema.sql v8.45. Новая миграция 2026_06_22_120000 метаданные-only выравнивает дефолт под канон. squawk 0 issues, применено dev+testing, проверено psql. CHANGELOG v8.50 + шапка schema.sql. TDD NotifPrefsDefaultNoReminderTest. FN-1 переоценён как не-баг кода: resolvePlatforms даёт B2+B3 корректно, B3-miss — supplier-side Doubles, джоба сама ретраит. Зафиксировано в отчёте приёмки. Прод не трогался. Накат — позже вместе с остальным. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
52 lines
2.1 KiB
PHP
52 lines
2.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\EmailVerification;
|
|
use App\Models\Tenant;
|
|
use App\Models\User;
|
|
use App\Services\Auth\RegistrationService;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Str;
|
|
|
|
// FN-3 (приёмка 22.06.2026): онбординг-confirm активировал владельца, но НЕ ставил
|
|
// users.email_verified_at — поле оставалось NULL, хотя email фактически подтверждён
|
|
// кодом из письма. Контракт: успешный confirm проставляет email_verified_at.
|
|
//
|
|
// confirm() работает через BYPASSRLS-соединение pgsql_supplier; создаём фикстуры на
|
|
// нём же (одна видимость) внутри собственной транзакции с rollback — без утечки в БД.
|
|
test('RegistrationService::confirm проставляет users.email_verified_at', function () {
|
|
$conn = DB::connection('pgsql_supplier');
|
|
$conn->beginTransaction();
|
|
|
|
try {
|
|
$tenant = Tenant::on('pgsql_supplier')->create(Tenant::factory()->raw());
|
|
$user = User::on('pgsql_supplier')->create(User::factory()->raw([
|
|
'tenant_id' => $tenant->id,
|
|
'email' => 'confirm-verified@example.ru',
|
|
'password_hash' => Hash::make('start-pass-1234'),
|
|
'is_active' => false,
|
|
'email_verified_at' => null,
|
|
]));
|
|
|
|
EmailVerification::on('pgsql_supplier')->create([
|
|
'user_id' => $user->id,
|
|
'email' => 'confirm-verified@example.ru',
|
|
'token' => (string) Str::uuid(),
|
|
'code_hash' => Hash::make('123456'),
|
|
'failed_attempts' => 0,
|
|
'expires_at' => now()->addMinutes(10),
|
|
'verified_at' => null,
|
|
]);
|
|
|
|
app(RegistrationService::class)->confirm('confirm-verified@example.ru', '123456');
|
|
|
|
$fresh = User::on('pgsql_supplier')->find($user->id);
|
|
expect($fresh->is_active)->toBeTrue();
|
|
expect($fresh->email_verified_at)->not->toBeNull();
|
|
} finally {
|
|
$conn->rollBack();
|
|
}
|
|
});
|