package ru.pdguard; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.DynamicTest.dynamicTest; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; import ru.pdguard.config.SystemPolicy; import ru.pdguard.core.PayloadStore; import ru.pdguard.core.Pipeline; import ru.pdguard.detect.RuleRegistry; import ru.pdguard.detect.Span; import ru.pdguard.mask.Masker; /** * 200 вручную составленных текстовых тестов из {@code dataset-200.txt} — по одному предложению на * строку, каждое своя отдельная проверка (не сборка одного большого текста, как в {@link * HugeDatasetTest}). Набор покрывает все типы ПДН из {@link RuleRegistry} (кроме * ADDRESS_REGION/ADDRESS_DISTRICT — для них нет правил, только модель второй ступени), варианты * написания (регистр, формат даты, разделяющие слова) и несколько строк-ловушек без разметки * (известный человек, адрес отделения, дата без якоря) — они не должны маскироваться вовсе. * *

На каждой строке: маскирование не оставляет исходное значение ПДН в открытом виде, а * демаскирование побайтово восстанавливает исходный текст. */ class Dataset200Test { private static final RuleRegistry REGISTRY = new RuleRegistry(); private static final Masker MASKER = new Masker(); private static final List DATASET = BenchmarkFixtures.load("/dataset-200.txt"); @TestFactory Stream datasetOf200Cases() { List cases = new java.util.ArrayList<>(DATASET.size()); for (int i = 0; i < DATASET.size(); i++) { BenchmarkFixtures.Sample sample = DATASET.get(i); int index = i; cases.add( dynamicTest( String.format("#%03d: %s", index, preview(sample.text())), () -> runCase(sample, index))); } return cases.stream(); } private void runCase(BenchmarkFixtures.Sample sample, int index) { Pipeline pipeline = new Pipeline(REGISTRY, MASKER, new PayloadStore(1_000_000L, 30)); String payloadId = "dataset200-" + index; String masked = pipeline.process(sample.text(), payloadId, SystemPolicy.DEFAULT); for (Span gold : sample.gold()) { String value = sample.text().substring(gold.start(), gold.end()); assertFalse( masked.contains(value), "ПДН типа " + gold.type() + " утекло в замаскированный текст: " + value); } String restored = pipeline.process(masked, payloadId, SystemPolicy.DEFAULT); assertEquals(sample.text(), restored, "демаскирование не восстановило исходный текст"); } private static String preview(String text) { return text.length() <= 40 ? text : text.substring(0, 40) + "..."; } }