Files
portal/app/tests/Feature/Logging/PiiScrubbingProcessorTest.php
T
Дмитрий 7f5288726a feat(security): PII-scrubbing процессор логов — Medium go-live
Monolog PiiScrubbingProcessor (телефоны/email -> [PHONE]/[EMAIL]) + ScrubPii tap на single/daily в config/logging.php. Pest 6/6 GREEN. Sentry-scrubbing (OPEN-И-16) не реализуем: sentry-laravel не установлен — open-item.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 20:43:28 +03:00

58 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
use App\Logging\PiiScrubbingProcessor;
use Monolog\Level;
use Monolog\LogRecord;
function piiTestRecord(string $message, array $context = []): LogRecord
{
return new LogRecord(new DateTimeImmutable, 'testing', Level::Error, $message, $context);
}
test('маскирует телефон РФ в message → [PHONE]', function () {
$out = (new PiiScrubbingProcessor)(piiTestRecord('Сбой для 79161234567 при импорте'));
expect($out->message)->toBe('Сбой для [PHONE] при импорте')
->and($out->message)->not->toContain('79161234567');
});
test('маскирует +7 и 8 форматы телефона', function () {
$p = new PiiScrubbingProcessor;
expect($p(piiTestRecord('a +79161234567 b'))->message)->toBe('a [PHONE] b')
->and($p(piiTestRecord('a 89161234567 b'))->message)->toBe('a [PHONE] b');
});
test('маскирует email в message → [EMAIL]', function () {
$out = (new PiiScrubbingProcessor)(piiTestRecord('user ivan@example.ru вошёл'));
expect($out->message)->toBe('user [EMAIL] вошёл');
});
test('маскирует телефон и email во вложенном context', function () {
$out = (new PiiScrubbingProcessor)(piiTestRecord('msg', [
'phone' => '79991234567',
'nested' => ['email' => 'a@b.ru', 'note' => 'без пдн'],
]));
expect($out->context['phone'])->toBe('[PHONE]')
->and($out->context['nested']['email'])->toBe('[EMAIL]')
->and($out->context['nested']['note'])->toBe('без пдн');
});
test('не маскирует длинную цифровую строку (14 цифр) — нет ложного срабатывания', function () {
$out = (new PiiScrubbingProcessor)(piiTestRecord('id 79161234567890 ok'));
expect($out->message)->toBe('id 79161234567890 ok');
});
test('не-строковые значения context сохраняются как есть', function () {
$out = (new PiiScrubbingProcessor)(piiTestRecord('msg', ['count' => 42, 'flag' => true, 'nil' => null]));
expect($out->context['count'])->toBe(42)
->and($out->context['flag'])->toBe(true)
->and($out->context['nil'])->toBeNull();
});