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.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; /** Проверки маскирования и обратного преобразования без подъёма HTTP-слоя. */ class PipelineTest { private static final String VALID_CARD = "4111 1111 1111 1111"; private static final String VALID_INN_12 = "770301234550"; private static final String VALID_SNILS = "112-233-445 95"; private Pipeline pipeline() { return new Pipeline(new RuleRegistry(), new Masker(), new PayloadStore(1_000_000L, 30)); } private String mask(Pipeline pipeline, String text) { return pipeline.process(text, UUID.randomUUID().toString(), SystemPolicy.DEFAULT); } @Test void masksCardNumber() { String masked = mask(pipeline(), "Оплата картой " + VALID_CARD + " прошла"); assertFalse(masked.contains(VALID_CARD), "номер карты остался в тексте: " + masked); assertTrue(masked.contains("41** **** **** **11"), masked); assertTrue(masked.startsWith("Оплата картой "), "окружающий текст изменён: " + masked); } @Test void keepsNumberThatFailsLuhn() { String text = "Заказ 1234 5678 9012 3456 отгружен"; assertEquals(text, mask(pipeline(), text)); } @Test void masksEmailKeepingTopLevelDomain() { String masked = mask(pipeline(), "Почта ivan.petrov@mail.ru для связи"); assertEquals("Почта i**********@m***.ru для связи", masked); } @Test void masksPhoneInAnyNotation() { Pipeline pipeline = pipeline(); for (String phone : new String[]{"+7 (916) 123-45-67", "89161234567", "8 916 123 45 67"}) { String masked = mask(pipeline, "Телефон " + phone); assertFalse(masked.contains(phone), "телефон остался в тексте: " + masked); assertTrue(masked.endsWith("67"), masked); } } @Test void masksInnByContextAndByChecksum() { Pipeline pipeline = pipeline(); assertFalse(mask(pipeline, "ИНН: " + VALID_INN_12).contains(VALID_INN_12)); assertFalse(mask(pipeline, "Реквизиты " + VALID_INN_12 + " проверены").contains(VALID_INN_12)); } @Test void masksSnils() { String masked = mask(pipeline(), "СНИЛС " + VALID_SNILS); assertFalse(masked.contains(VALID_SNILS), masked); } @Test void unmaskingRestoresOriginalText() { Pipeline pipeline = pipeline(); String original = "Карта " + VALID_CARD + ", почта ivan@mail.ru, телефон +7 916 123-45-67"; String id = "pair-1"; String masked = pipeline.process(original, id, SystemPolicy.DEFAULT); assertNotEquals(original, masked); String restored = pipeline.process(masked, id, SystemPolicy.DEFAULT); assertEquals(original, restored); } @Test void retryReturnsSameMask() { Pipeline pipeline = pipeline(); String original = "Карта " + VALID_CARD; String id = "retry-1"; String first = pipeline.process(original, id, SystemPolicy.DEFAULT); String second = pipeline.process(original, id, SystemPolicy.DEFAULT); assertEquals(first, second); } @Test void unmasksWhenPayloadIdIsUnknown() { Pipeline pipeline = pipeline(); String original = "Почта ivan@mail.ru"; String masked = pipeline.process(original, "lost-id", SystemPolicy.DEFAULT); assertEquals(original, pipeline.process(masked, "другой-идентификатор", SystemPolicy.DEFAULT)); } @Test void textWithoutPersonalDataIsUnchanged() { String text = "Расскажи о погоде в Москве завтра"; assertEquals(text, mask(pipeline(), text)); } @Test void systemPolicyDisablesSelectedTypes() { Pipeline pipeline = pipeline(); SystemPolicy onlyEmail = SystemPolicy.forTypes(RuleRegistry.EMAIL); String masked = pipeline.process("Карта " + VALID_CARD + ", почта ivan@mail.ru", "policy-1", onlyEmail); assertTrue(masked.contains(VALID_CARD), "карта не должна маскироваться этой системой: " + masked); assertFalse(masked.contains("ivan@mail.ru"), masked); } @Test void handlesLargeText() { Pipeline pipeline = pipeline(); String block = "Клиент написал с адреса ivan@mail.ru и оплатил картой " + VALID_CARD + ". "; String large = block.repeat(4000); long started = System.nanoTime(); String masked = pipeline.process(large, "large-1", SystemPolicy.DEFAULT); long millis = (System.nanoTime() - started) / 1_000_000; assertFalse(masked.contains("ivan@mail.ru")); assertEquals(large, pipeline.process(masked, "large-1", SystemPolicy.DEFAULT)); assertTrue(millis < 1000, "обработка крупного текста заняла " + millis + " мс"); } }