PD Guard: модуль безопасности персональных данных

This commit is contained in:
Onbehalfofme
2026-09-22 17:43:33 +03:00
commit 41052fac6a
80 changed files with 91230 additions and 0 deletions
+131
View File
@@ -0,0 +1,131 @@
package ru.pdguard;
import org.junit.jupiter.api.Test;
import ru.pdguard.config.SystemPolicy;
import ru.pdguard.core.PayloadStore;
import ru.pdguard.core.Pipeline;
import ru.pdguard.detect.RuleRegistry;
import ru.pdguard.mask.Masker;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** ФИО и защита от ложных срабатываний. */
class FioTest {
private final Pipeline pipeline =
new Pipeline(new RuleRegistry(), new Masker(), new PayloadStore(1_000_000L, 30));
private String mask(String text) {
return pipeline.process(text, UUID.randomUUID().toString(), SystemPolicy.DEFAULT);
}
private void assertHidden(String text, String secret) {
String masked = mask(text);
assertFalse(masked.contains(secret), "не замаскировано: «" + secret + "» в ответе «" + masked + "»");
}
private void assertUnchanged(String text) {
assertEquals(text, mask(text), "ложное срабатывание");
}
@Test
void masksFullNameAsInitials() {
assertEquals("Клиент И. И. И. обратился", mask("Клиент Иванов Иван Иванович обратился"));
}
@Test
void masksNameAndPatronymicWithoutSurname() {
assertHidden("Пригласите Ивана Сергеевича на встречу", "Ивана Сергеевича");
}
@Test
void masksFemalePatronymic() {
assertHidden("Петрова Анна Ивановна подписала", "Петрова Анна Ивановна");
assertHidden("Мария Никитична ждёт ответа", "Мария Никитична");
}
@Test
void masksSurnameWithInitialsInBothOrders() {
assertHidden("Заявление от Иванов И.И. принято", "Иванов И.И.");
assertHidden("Подписал И.И. Иванов", "И.И. Иванов");
}
@Test
void masksSurnameNextToKnownGivenName() {
assertHidden("Петров Сергей подтвердил заявку", "Петров Сергей");
assertHidden("Сергей Петров подтвердил заявку", "Сергей Петров");
assertHidden("Обращение Ольги Ковалёвой рассмотрено", "Ольги Ковалёвой");
}
@Test
void masksLowercaseNameAfterExplicitAnchor() {
assertHidden("ФИО: иванов иван иванович", "иванов иван иванович");
assertHidden("Карта оформлена на имя петров сергей", "петров сергей");
}
@Test
void masksNameAfterRoleAnchor() {
assertHidden("Клиент Петров Сергей, заявка одобрена", "Петров Сергей");
assertHidden("Плательщик Ковалёва подтвердила перевод", "Ковалёва");
}
@Test
void doesNotMaskWellKnownPerson() {
assertUnchanged("Напиши стихотворение в духе Александра Пушкина про осень");
assertUnchanged("Сравни Толстого и Достоевского как прозаиков");
assertUnchanged("Когда Гагарин полетел в космос");
}
@Test
void masksWellKnownSurnameWhenOtherPersonalDataIsPresent() {
assertHidden("Клиент Александр Пушкин, паспорт 4509 123456", "Александр Пушкин");
}
@Test
void doesNotMaskPlaceNamesThatLookLikeSurnames() {
assertUnchanged("Московский Кремль открыт для посещения");
assertUnchanged("Экскурсия в Нижний Новгород перенесена");
assertUnchanged("Смоленская площадь закрыта на ремонт");
}
@Test
void doesNotMaskOrdinaryCapitalisedWords() {
assertUnchanged("Банк Открытие подтвердил лимит");
assertUnchanged("В Понедельник Отдел Согласует Договор");
}
@Test
void identificationIgnoresCase() {
assertHidden("ИВАНОВ ИВАН ИВАНОВИЧ", "ИВАНОВ ИВАН ИВАНОВИЧ");
assertHidden("фио: петрова анна ивановна", "петрова анна ивановна");
}
@Test
void unmaskingRestoresNames() {
String original = "Клиент Иванов Иван Иванович, паспорт 4509 123456, "
+ "дата рождения 12.05.1985, телефон +7 916 123-45-67";
String id = "fio-1";
String masked = pipeline.process(original, id, SystemPolicy.DEFAULT);
assertFalse(masked.contains("Иванов Иван Иванович"), masked);
assertTrue(masked.contains("И. И. И."), masked);
assertEquals(original, pipeline.process(masked, id, SystemPolicy.DEFAULT));
}
@Test
void namesStayFastOnLargeText() {
String block = "Клиент Иванов Иван Иванович, паспорт 4509 123456, город Москва. ";
String large = block.repeat(4000);
long started = System.nanoTime();
String masked = pipeline.process(large, "fio-large", SystemPolicy.DEFAULT);
long millis = (System.nanoTime() - started) / 1_000_000;
assertFalse(masked.contains("Иванов Иван Иванович"));
assertTrue(millis < 1000, "обработка заняла " + millis + " мс");
}
}