This is an automated email from the ASF dual-hosted git repository.
THausherr pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tika.git
The following commit(s) were added to refs/heads/main by this push:
new b08d4c2057 [TIKA-4841] Add unit tests for Metadata reserved-key
blocking, write limiter, and composite properties (#2948)
b08d4c2057 is described below
commit b08d4c20571a294f9be23d76ae5a64d97b5ce54f
Author: Vasiliy Mikhailov <[email protected]>
AuthorDate: Wed Aug 26 16:14:38 2026 +0300
[TIKA-4841] Add unit tests for Metadata reserved-key blocking, write
limiter, and composite properties (#2948)
---
.../org/apache/tika/metadata/TestMetadata.java | 119 +++++++++++++++++++++
1 file changed, 119 insertions(+)
diff --git a/tika-core/src/test/java/org/apache/tika/metadata/TestMetadata.java
b/tika-core/src/test/java/org/apache/tika/metadata/TestMetadata.java
index e1fc1f62bc..5f2d6a233e 100644
--- a/tika-core/src/test/java/org/apache/tika/metadata/TestMetadata.java
+++ b/tika-core/src/test/java/org/apache/tika/metadata/TestMetadata.java
@@ -18,8 +18,10 @@ package org.apache.tika.metadata;
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.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@@ -27,6 +29,7 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
+import java.util.Map;
import java.util.Random;
import java.util.TimeZone;
import java.util.concurrent.Callable;
@@ -38,6 +41,7 @@ import java.util.concurrent.Future;
import org.junit.jupiter.api.Test;
import org.apache.tika.TikaTest;
+import org.apache.tika.metadata.writelimiter.MetadataWriteLimiter;
import org.apache.tika.utils.DateUtils;
//Junit imports
@@ -461,6 +465,121 @@ public class TestMetadata extends TikaTest {
assertEquals("key=value1", m.toString());
}
+ /**
+ * Two Metadata instances that differ only in a value under the same key
+ * must not be equal, so value-distinct metadata are never collapsed.
+ */
+ @Test
+ public void testValueDistinctMetadataNotEqual() {
+ Metadata m1 = new Metadata();
+ m1.add("k1", "v1");
+ Metadata m2 = new Metadata();
+ m2.add("k1", "v2");
+ assertNotEquals(m1, m2);
+ }
+
+ /**
+ * Writing to reserved keys must throw an exception.
+ */
+ @Test
+ public void testReservedKeyBlockedOnUntrustedMetadata() {
+ String reservedKey = TikaCoreProperties.TIKA_META_PREFIX + "reserved";
+ Metadata m = new Metadata();
+ assertThrows(IllegalArgumentException.class, () -> m.add(reservedKey,
"value"));
+ }
+
+ /**
+ * Reserved keys are accepted when addTrusted() is used.
+ */
+ @Test
+ public void testReservedKeyAllowedOnTrustedMetadata() {
+ String reservedKey = TikaCoreProperties.TIKA_META_PREFIX + "reserved";
+ Metadata m = new Metadata();
+ m.addTrusted(reservedKey, "value");
+ assertEquals("value", m.get(reservedKey));
+ }
+
+ /**
+ * A write limiter that drops everything must prevent {@code set} from
+ * persisting a value, so persistence stays under the limiter's control.
+ */
+ @Test
+ public void testWriteLimiterBlocksSet() {
+ Metadata m = new Metadata(blockingLimiter());
+ m.set("key", "value");
+ assertNull(m.get("key"));
+ }
+
+ /**
+ * {@code set(String, String)} must delegate to the limiter with the exact
+ * field and value it was given.
+ */
+ @Test
+ public void testWriteLimiterInvokedOnSet() {
+ RecordingLimiter limiter = new RecordingLimiter();
+ Metadata m = new Metadata(limiter);
+ m.set("key", "value");
+ assertTrue(limiter.setCalled);
+ assertEquals("key", limiter.lastSetField);
+ assertEquals("value", limiter.lastSetValue);
+ }
+
+ /**
+ * The {@code set(Property, String)} overload must delegate to the limiter
+ * using the property's name and the given value.
+ */
+ @Test
+ public void testWriteLimiterInvokedOnSetProperty() {
+ RecordingLimiter limiter = new RecordingLimiter();
+ Metadata m = new Metadata(limiter);
+ m.set(TikaCoreProperties.TITLE, "title");
+ assertTrue(limiter.setCalled);
+ assertEquals(TikaCoreProperties.TITLE.getName(), limiter.lastSetField);
+ assertEquals("title", limiter.lastSetValue);
+ }
+
+ /**
+ * A write limiter that ignores every field, so nothing is persisted.
+ */
+ private static MetadataWriteLimiter blockingLimiter() {
+ return new MetadataWriteLimiter() {
+ @Override
+ public void add(String field, String value, Map<String, String[]>
data) {
+ }
+
+ @Override
+ public void set(String field, String value, Map<String, String[]>
data) {
+ }
+ };
+ }
+
+ /**
+ * A spy limiter that records the field and value it was invoked with on
+ * {@code set} and writes the value through to the backing map.
+ */
+ private static final class RecordingLimiter implements
MetadataWriteLimiter {
+ private boolean setCalled;
+ private String lastSetField;
+ private String lastSetValue;
+
+ @Override
+ public void add(String field, String value, Map<String, String[]>
data) {
+ if (value != null) {
+ data.put(field, new String[]{value});
+ }
+ }
+
+ @Override
+ public void set(String field, String value, Map<String, String[]>
data) {
+ setCalled = true;
+ lastSetField = field;
+ lastSetValue = value;
+ if (value != null) {
+ data.put(field, new String[]{value});
+ }
+ }
+ }
+
private static class MetadataDateAdder implements Callable<Integer> {
private final Random random = new Random();