This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


The following commit(s) were added to refs/heads/master by this push:
     new 5431086910 JAMES-4143 Add a custom header Field for JMAP rule matching 
(#2811)
5431086910 is described below

commit 54310869108003c678a36e4712b9da41a16d180c
Author: Benoit TELLIER <btell...@linagora.com>
AuthorDate: Tue Sep 16 11:56:20 2025 +0200

    JAMES-4143 Add a custom header Field for JMAP rule matching (#2811)
---
 .../src/test/resources/json/event-v4.json          |  5 ++
 .../org/apache/james/jmap/api/filtering/Rule.java  | 53 +++++++++++++++-------
 .../james/jmap/api/filtering/RuleFixture.java      | 25 +++++-----
 .../impl/FilterUsernameChangeTaskStepTest.java     |  2 +-
 .../mailets/FilterForwardIntegrationTest.java      |  2 +-
 .../james/mailets/ForwardLoopIntegrationTest.java  |  2 +-
 .../james/jmap/mailet/filter/ContentMatcher.java   | 20 ++++----
 .../james/jmap/mailet/filter/HeaderExtractor.java  | 20 +++++---
 .../jmap/mailet/filter/JMAPFilteringTest.java      | 40 ++++++++++------
 .../memory/MemoryUserDeletionIntegrationTest.java  |  2 +-
 .../MemoryUsernameChangeIntegrationTest.java       |  2 +-
 ...pulateFilteringProjectionRequestToTaskTest.java |  2 +-
 12 files changed, 112 insertions(+), 63 deletions(-)

diff --git 
a/server/data/data-jmap-cassandra/src/test/resources/json/event-v4.json 
b/server/data/data-jmap-cassandra/src/test/resources/json/event-v4.json
index f4b9e9f403..e354e06566 100644
--- a/server/data/data-jmap-cassandra/src/test/resources/json/event-v4.json
+++ b/server/data/data-jmap-cassandra/src/test/resources/json/event-v4.json
@@ -13,6 +13,11 @@
             "field": "cc",
             "comparator": "contains",
             "value": "something"
+          },
+          {
+            "field": "header:custom",
+            "comparator": "contains",
+            "value": "another thing"
           }
         ]
       },
diff --git 
a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/filtering/Rule.java
 
b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/filtering/Rule.java
index 234623f981..89effc3fb9 100644
--- 
a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/filtering/Rule.java
+++ 
b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/filtering/Rule.java
@@ -129,33 +129,52 @@ public class Rule {
 
     public static class Condition {
 
-        public enum Field {
-            FROM("from"),
-            TO("to"),
-            CC("cc"),
-            SUBJECT("subject"),
-            RECIPIENT("recipient");
-            
-            public static Optional<Field> find(String fieldName) {
-                return Arrays.stream(values())
-                        .filter(value -> 
value.fieldName.equalsIgnoreCase(fieldName))
-                        .findAny();
+        public interface Field {
+            static Optional<Field> find(String fieldName) {
+                return FixedField.find(fieldName)
+                    .or(() -> CustomHeaderField.find(fieldName));
             }
             
-            public static Field of(String fieldName) {
+            static Field of(String fieldName) {
                 return find(fieldName).orElseThrow(() -> new 
IllegalArgumentException("'" + fieldName + "' is not a valid field name"));
             }
             
-            private final String fieldName;
-            
-            Field(String fieldName) {
-                this.fieldName = fieldName;
+            String asString();
+        }
+
+        public record FixedField(String fieldName) implements Field {
+            public static Field FROM = new FixedField("from");
+            public static Field TO = new FixedField("to");
+            public static Field CC = new FixedField("cc");
+            public static Field SUBJECT = new FixedField("subject");
+            public static Field RECIPIENT = new FixedField("recipient");
+            public static final ImmutableList<Field> VALUES = 
ImmutableList.of(FROM, TO, CC, SUBJECT, RECIPIENT);
+
+            public static Optional<Field> find(String fieldName) {
+                return VALUES.stream()
+                    .filter(value -> 
value.asString().equalsIgnoreCase(fieldName))
+                    .findAny();
             }
-            
+
             public String asString() {
                 return fieldName;
             }
         }
+
+        public record CustomHeaderField(String headerName) implements Field {
+            public static final String PREFIX = "header:";
+
+            public static Optional<Field> find(String fieldName) {
+                if (fieldName.startsWith(PREFIX)) {
+                    return Optional.of(new 
CustomHeaderField(fieldName.substring(PREFIX.length())));
+                }
+                return Optional.empty();
+            }
+
+            public String asString() {
+                return PREFIX + headerName;
+            }
+        }
         
         public enum Comparator {
             CONTAINS("contains"),
diff --git 
a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/filtering/RuleFixture.java
 
b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/filtering/RuleFixture.java
index da36eb27ab..6ad3285bdf 100644
--- 
a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/filtering/RuleFixture.java
+++ 
b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/filtering/RuleFixture.java
@@ -28,7 +28,7 @@ import com.google.common.collect.ImmutableList;
 
 public interface RuleFixture {
     String NAME = "a name";
-    Rule.Condition CONDITION = Rule.Condition.of(Rule.Condition.Field.CC, 
Rule.Condition.Comparator.CONTAINS, "something");
+    Rule.Condition CONDITION = Rule.Condition.of(Rule.Condition.FixedField.CC, 
Rule.Condition.Comparator.CONTAINS, "something");
     Rule.Action ACTION = 
Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds("id-01"),
         true,
         true,
@@ -55,7 +55,8 @@ public interface RuleFixture {
     Rule RULE_2 = RULE_BUILDER.id(Rule.Id.of("2")).build();
     Rule RULE_3 = RULE_BUILDER.id(Rule.Id.of("3")).build();
     Rule RULE_4 = Rule.builder()
-        .conditionGroup(CONDITION)
+        .conditionGroup(Rule.ConditionGroup.of(Rule.ConditionCombiner.AND, 
CONDITION,
+            Rule.Condition.of(new Rule.Condition.CustomHeaderField("custom"), 
Rule.Condition.Comparator.CONTAINS, "another thing")))
         .action(ACTION_2)
         .id(Rule.Id.of("1"))
         .name(NAME)
@@ -66,7 +67,7 @@ public interface RuleFixture {
         .name(NAME)
         
.action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds("mbx1")))
         .conditionGroup(Rule.Condition.of(
-            Rule.Condition.Field.TO,
+            Rule.Condition.FixedField.TO,
             Rule.Condition.Comparator.EXACTLY_EQUALS,
             "A value to match 1"))
         .build();
@@ -76,7 +77,7 @@ public interface RuleFixture {
         .name(NAME)
         
.action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds("mbx1")))
         .conditionGroup(Rule.Condition.of(
-            Rule.Condition.Field.SUBJECT,
+            Rule.Condition.FixedField.SUBJECT,
             Rule.Condition.Comparator.NOT_CONTAINS,
             "A value to match 2"))
         .build();
@@ -86,7 +87,7 @@ public interface RuleFixture {
         .name(NAME)
         
.action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds("mbx1")))
         .conditionGroup(Rule.Condition.of(
-            Rule.Condition.Field.RECIPIENT,
+            Rule.Condition.FixedField.RECIPIENT,
             Rule.Condition.Comparator.NOT_EXACTLY_EQUALS,
             "A value to match 3"))
         .build();
@@ -96,7 +97,7 @@ public interface RuleFixture {
         .name(NAME)
         
.action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds("mbx1")))
         .conditionGroup(Rule.Condition.of(
-            Rule.Condition.Field.FROM,
+            Rule.Condition.FixedField.FROM,
             Rule.Condition.Comparator.CONTAINS,
             "A value to match 4"))
         .build();
@@ -106,7 +107,7 @@ public interface RuleFixture {
         .name(NAME)
         
.action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds("mbx1")))
         .conditionGroup(Rule.Condition.of(
-            Rule.Condition.Field.CC,
+            Rule.Condition.FixedField.CC,
             Rule.Condition.Comparator.START_WITH,
             "A value to match 5"))
         .build();
@@ -116,7 +117,7 @@ public interface RuleFixture {
         .name(NAME)
         .action(ACTION_2)
         .conditionGroup(Rule.Condition.of(
-            Rule.Condition.Field.TO,
+            Rule.Condition.FixedField.TO,
             Rule.Condition.Comparator.EXACTLY_EQUALS,
             "A value to match 1"))
         .build();
@@ -126,7 +127,7 @@ public interface RuleFixture {
         .name(NAME)
         .action(ACTION_2)
         .conditionGroup(Rule.Condition.of(
-            Rule.Condition.Field.SUBJECT,
+            Rule.Condition.FixedField.SUBJECT,
             Rule.Condition.Comparator.NOT_CONTAINS,
             "A value to match 2"))
         .build();
@@ -136,7 +137,7 @@ public interface RuleFixture {
         .name(NAME)
         .action(ACTION_2)
         .conditionGroup(Rule.Condition.of(
-            Rule.Condition.Field.RECIPIENT,
+            Rule.Condition.FixedField.RECIPIENT,
             Rule.Condition.Comparator.NOT_EXACTLY_EQUALS,
             "A value to match 3"))
         .build();
@@ -146,7 +147,7 @@ public interface RuleFixture {
         .name(NAME)
         .action(ACTION_2)
         .conditionGroup(Rule.Condition.of(
-            Rule.Condition.Field.FROM,
+            Rule.Condition.FixedField.FROM,
             Rule.Condition.Comparator.CONTAINS,
             "A value to match 4"))
         .build();
@@ -156,7 +157,7 @@ public interface RuleFixture {
         .name(NAME)
         .action(ACTION_2)
         .conditionGroup(Rule.Condition.of(
-            Rule.Condition.Field.CC,
+            Rule.Condition.FixedField.CC,
             Rule.Condition.Comparator.START_WITH,
             "A value to match 5"))
         .build();
diff --git 
a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/filtering/impl/FilterUsernameChangeTaskStepTest.java
 
b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/filtering/impl/FilterUsernameChangeTaskStepTest.java
index 3ef04bdba1..9f7a3f5795 100644
--- 
a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/filtering/impl/FilterUsernameChangeTaskStepTest.java
+++ 
b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/filtering/impl/FilterUsernameChangeTaskStepTest.java
@@ -42,7 +42,7 @@ public class FilterUsernameChangeTaskStepTest {
     private static final Optional<Version> NO_VERSION = Optional.empty();
 
     private static final String NAME = "a name";
-    private static final Rule.Condition CONDITION = 
Rule.Condition.of(Rule.Condition.Field.CC, Rule.Condition.Comparator.CONTAINS, 
"something");
+    private static final Rule.Condition CONDITION = 
Rule.Condition.of(Rule.Condition.FixedField.CC, 
Rule.Condition.Comparator.CONTAINS, "something");
     private static final Rule.Action ACTION = 
Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds("id-01"));
     private static final Rule.Builder RULE_BUILDER = 
Rule.builder().name(NAME).conditionGroup(CONDITION).action(ACTION);
     private static final Rule RULE_1 = 
RULE_BUILDER.id(Rule.Id.of("1")).build();
diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/FilterForwardIntegrationTest.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/FilterForwardIntegrationTest.java
index 89cfaf6784..d5bde11b11 100644
--- 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/FilterForwardIntegrationTest.java
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/FilterForwardIntegrationTest.java
@@ -20,7 +20,7 @@
 package org.apache.james.mailets;
 
 import static 
org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.CONTAINS;
-import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.FROM;
+import static 
org.apache.james.jmap.api.filtering.Rule.Condition.FixedField.FROM;
 import static 
org.apache.james.mailets.configuration.CommonProcessors.RRT_ERROR_REPOSITORY;
 import static org.apache.james.mailets.configuration.Constants.DEFAULT_DOMAIN;
 import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP;
diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardLoopIntegrationTest.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardLoopIntegrationTest.java
index 69a4228e08..700776ea6b 100644
--- 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardLoopIntegrationTest.java
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardLoopIntegrationTest.java
@@ -20,7 +20,7 @@
 package org.apache.james.mailets;
 
 import static 
org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.NOT_CONTAINS;
-import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.FROM;
+import static 
org.apache.james.jmap.api.filtering.Rule.Condition.FixedField.FROM;
 import static 
org.apache.james.mailets.configuration.CommonProcessors.RRT_ERROR_REPOSITORY;
 import static org.apache.james.mailets.configuration.Constants.DEFAULT_DOMAIN;
 import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP;
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java
 
b/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java
index fd62f30215..ddd8f71b8e 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java
+++ 
b/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java
@@ -32,6 +32,7 @@ import org.apache.james.util.OptionalUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 
 public interface ContentMatcher {
@@ -122,11 +123,11 @@ public interface ContentMatcher {
         .build();
 
     Map<Rule.Condition.Field, Map<Rule.Condition.Comparator, ContentMatcher>> 
CONTENT_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Field, 
Map<Rule.Condition.Comparator, ContentMatcher>>builder()
-        .put(Rule.Condition.Field.SUBJECT, CONTENT_STRING_MATCHER_REGISTRY)
-        .put(Rule.Condition.Field.TO, HEADER_ADDRESS_MATCHER_REGISTRY)
-        .put(Rule.Condition.Field.CC, HEADER_ADDRESS_MATCHER_REGISTRY)
-        .put(Rule.Condition.Field.RECIPIENT, HEADER_ADDRESS_MATCHER_REGISTRY)
-        .put(Rule.Condition.Field.FROM, HEADER_ADDRESS_MATCHER_REGISTRY)
+        .put(Rule.Condition.FixedField.SUBJECT, 
CONTENT_STRING_MATCHER_REGISTRY)
+        .put(Rule.Condition.FixedField.TO, HEADER_ADDRESS_MATCHER_REGISTRY)
+        .put(Rule.Condition.FixedField.CC, HEADER_ADDRESS_MATCHER_REGISTRY)
+        .put(Rule.Condition.FixedField.RECIPIENT, 
HEADER_ADDRESS_MATCHER_REGISTRY)
+        .put(Rule.Condition.FixedField.FROM, HEADER_ADDRESS_MATCHER_REGISTRY)
         .build();
 
     static ContentMatcher negate(ContentMatcher contentMatcher) {
@@ -135,9 +136,12 @@ public interface ContentMatcher {
     }
 
     static Optional<ContentMatcher> asContentMatcher(Rule.Condition.Field 
field, Rule.Condition.Comparator comparator) {
-        return Optional
-            .ofNullable(CONTENT_MATCHER_REGISTRY.get(field))
-            .map(matcherRegistry -> matcherRegistry.get(comparator));
+        return Optional.ofNullable(CONTENT_MATCHER_REGISTRY.get(field))
+            .map(matcherRegistry -> matcherRegistry.get(comparator))
+            .or(() -> {
+                Preconditions.checkArgument(field instanceof 
Rule.Condition.CustomHeaderField);
+                return 
Optional.of(CONTENT_STRING_MATCHER_REGISTRY.get(comparator));
+            });
     }
 
     static AddressHeader asAddressHeader(String addressAsString) {
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/HeaderExtractor.java
 
b/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/HeaderExtractor.java
index 0f5e9f4ffc..72430ad960 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/HeaderExtractor.java
+++ 
b/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/HeaderExtractor.java
@@ -38,6 +38,7 @@ import org.slf4j.LoggerFactory;
 
 import com.github.fge.lambdas.Throwing;
 import com.github.fge.lambdas.functions.ThrowingFunction;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 
 public interface HeaderExtractor extends ThrowingFunction<Mail, 
Stream<String>> {
@@ -51,11 +52,11 @@ public interface HeaderExtractor extends 
ThrowingFunction<Mail, Stream<String>>
     HeaderExtractor FROM_EXTRACTOR = addressExtractor(mail -> 
mail.getMessage().getHeader(FROM), FROM);
 
     Map<Rule.Condition.Field, HeaderExtractor> HEADER_EXTRACTOR_REGISTRY = 
ImmutableMap.<Rule.Condition.Field, HeaderExtractor>builder()
-        .put(Rule.Condition.Field.SUBJECT, SUBJECT_EXTRACTOR)
-        .put(Rule.Condition.Field.RECIPIENT, RECIPIENT_EXTRACTOR)
-        .put(Rule.Condition.Field.FROM, FROM_EXTRACTOR)
-        .put(Rule.Condition.Field.CC, CC_EXTRACTOR)
-        .put(Rule.Condition.Field.TO, TO_EXTRACTOR)
+        .put(Rule.Condition.FixedField.SUBJECT, SUBJECT_EXTRACTOR)
+        .put(Rule.Condition.FixedField.RECIPIENT, RECIPIENT_EXTRACTOR)
+        .put(Rule.Condition.FixedField.FROM, FROM_EXTRACTOR)
+        .put(Rule.Condition.FixedField.CC, CC_EXTRACTOR)
+        .put(Rule.Condition.FixedField.TO, TO_EXTRACTOR)
         .build();
 
     boolean STRICT_PARSING = true;
@@ -90,7 +91,12 @@ public interface HeaderExtractor extends 
ThrowingFunction<Mail, Stream<String>>
     }
 
     static Optional<HeaderExtractor> asHeaderExtractor(Rule.Condition.Field 
field) {
-        return Optional.ofNullable(
-            HeaderExtractor.HEADER_EXTRACTOR_REGISTRY.get(field));
+        return 
Optional.ofNullable(HeaderExtractor.HEADER_EXTRACTOR_REGISTRY.get(field))
+            .or(() -> {
+                Preconditions.checkArgument(field instanceof 
Rule.Condition.CustomHeaderField);
+                Rule.Condition.CustomHeaderField customHeaderField = 
(Rule.Condition.CustomHeaderField) field;
+
+                return Optional.of(mail -> 
StreamUtils.ofNullables(mail.getMessage().getHeader(customHeaderField.headerName())));
+            });
     }
 }
diff --git 
a/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
 
b/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
index c3648f30ae..86baf455b6 100644
--- 
a/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
+++ 
b/server/protocols/jmap-rfc-8621/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
@@ -25,11 +25,11 @@ import static 
org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.EXAC
 import static 
org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.NOT_CONTAINS;
 import static 
org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.NOT_EXACTLY_EQUALS;
 import static 
org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.START_WITH;
-import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.CC;
-import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.FROM;
-import static 
org.apache.james.jmap.api.filtering.Rule.Condition.Field.RECIPIENT;
-import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.SUBJECT;
-import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.TO;
+import static org.apache.james.jmap.api.filtering.Rule.Condition.FixedField.CC;
+import static 
org.apache.james.jmap.api.filtering.Rule.Condition.FixedField.FROM;
+import static 
org.apache.james.jmap.api.filtering.Rule.Condition.FixedField.RECIPIENT;
+import static 
org.apache.james.jmap.api.filtering.Rule.Condition.FixedField.SUBJECT;
+import static org.apache.james.jmap.api.filtering.Rule.Condition.FixedField.TO;
 import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.BOU;
 import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.EMPTY;
 import static 
org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.FRED_MARTIN_FULLNAME;
@@ -65,7 +65,6 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.core.Username;
 import org.apache.james.core.builder.MimeMessageBuilder;
 import org.apache.james.jmap.api.filtering.Rule;
-import org.apache.james.jmap.api.filtering.Rule.Condition.Field;
 import 
org.apache.james.jmap.mailet.filter.JMAPFilteringExtension.JMAPFilteringTestSystem;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.util.StreamUtils;
@@ -246,11 +245,11 @@ class JMAPFilteringTest {
     }
 
     public static final ImmutableList<FieldAndHeader> 
ADDRESS_TESTING_COMBINATION = ImmutableList.of(
-        new FieldAndHeader(Field.FROM, RFC2822Headers.FROM),
-        new FieldAndHeader(Field.TO, RFC2822Headers.TO),
-        new FieldAndHeader(Field.CC, RFC2822Headers.CC),
-        new FieldAndHeader(Field.RECIPIENT, RFC2822Headers.TO),
-        new FieldAndHeader(Field.RECIPIENT, RFC2822Headers.CC));
+        new FieldAndHeader(FROM, RFC2822Headers.FROM),
+        new FieldAndHeader(TO, RFC2822Headers.TO),
+        new FieldAndHeader(CC, RFC2822Headers.CC),
+        new FieldAndHeader(RECIPIENT, RFC2822Headers.TO),
+        new FieldAndHeader(RECIPIENT, RFC2822Headers.CC));
 
     static Stream<Arguments> exactlyEqualsTestSuite() {
         return StreamUtils.flatten(
@@ -394,7 +393,12 @@ class JMAPFilteringTest {
                     .valueToMatch(USER_4_FULL_ADDRESS)
                     .build(),
                 
argumentBuilder().scrambledSubjectToMatch(UNSCRAMBLED_SUBJECT).build(),
-                
argumentBuilder().unscrambledSubjectToMatch(UNSCRAMBLED_SUBJECT).build()));
+                
argumentBuilder().unscrambledSubjectToMatch(UNSCRAMBLED_SUBJECT).build(),
+                argumentBuilder(new 
Rule.Condition.CustomHeaderField("X-CUSTOM"))
+                    .description("X-CUSTOM")
+                    .header("X-CUSTOM", "abcdeg")
+                    .valueToMatch("abcdeg")
+                    .build()));
     }
 
     static Stream<Arguments> containsTestSuite() {
@@ -491,6 +495,11 @@ class JMAPFilteringTest {
                     .toRecipient(USER_3_FULL_ADDRESS)
                     .toRecipient(USER_4_FULL_ADDRESS)
                     .valueToMatch("user4@jam").build(),
+                argumentBuilder(new 
Rule.Condition.CustomHeaderField("X-CUSTOM"))
+                    .description("X-CUSTOM")
+                    .header("X-CUSTOM", "abcdeg")
+                    .valueToMatch("bcde")
+                    .build(),
                 argumentBuilder().scrambledSubjectToMatch("is the 
subject").build(),
                 argumentBuilder().unscrambledSubjectToMatch("rédéric 
MART").build()));
     }
@@ -562,6 +571,11 @@ class JMAPFilteringTest {
 
                     .map(FilteringArgumentBuilder::build)),
             Stream.of(
+                argumentBuilder(new 
Rule.Condition.CustomHeaderField("X-CUSTOM"))
+                    .description("X-CUSTOM")
+                    .header("X-CUSTOM", "abcdeg")
+                    .valueToMatch(SHOULD_NOT_MATCH)
+                    .build(),
                 argumentBuilder().description("multiple to and cc headers")
                     .field(RECIPIENT)
                     .ccRecipient(USER_1_FULL_ADDRESS)
@@ -579,7 +593,7 @@ class JMAPFilteringTest {
                 
argumentBuilder().scrambledSubjectShouldNotMatchCaseSensitive().build(),
                 
argumentBuilder().unscrambledSubjectToMatch(SHOULD_NOT_MATCH).build(),
                 
argumentBuilder().unscrambledSubjectShouldNotMatchCaseSensitive().build()),
-            Stream.of(Rule.Condition.Field.values())
+            Rule.Condition.FixedField.VALUES.stream()
                 .map(field -> argumentBuilder()
                     .description("no header")
                     .field(field)
diff --git 
a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUserDeletionIntegrationTest.java
 
b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUserDeletionIntegrationTest.java
index b6dc3e3a66..4ba7c8f697 100644
--- 
a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUserDeletionIntegrationTest.java
+++ 
b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUserDeletionIntegrationTest.java
@@ -240,7 +240,7 @@ class MemoryUserDeletionIntegrationTest {
 
     @Test
     void shouldDeleteFilters(GuiceJamesServer server) {
-        Rule.Condition condition = Rule.Condition.of(Rule.Condition.Field.CC, 
Rule.Condition.Comparator.CONTAINS, "something");
+        Rule.Condition condition = 
Rule.Condition.of(Rule.Condition.FixedField.CC, 
Rule.Condition.Comparator.CONTAINS, "something");
         Rule.Action action = 
Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds("id-01"));
         Rule.Builder ruleBuilder = Rule.builder().name("A 
name").conditionGroup(condition).action(action);
         Rule rule1 = ruleBuilder.id(Rule.Id.of("1")).build();
diff --git 
a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUsernameChangeIntegrationTest.java
 
b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUsernameChangeIntegrationTest.java
index 7324c3f60a..e9775155b4 100644
--- 
a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUsernameChangeIntegrationTest.java
+++ 
b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryUsernameChangeIntegrationTest.java
@@ -106,7 +106,7 @@ class MemoryUsernameChangeIntegrationTest {
     }
 
     private static final String NAME = "a name";
-    private static final Rule.Condition CONDITION = 
Rule.Condition.of(Rule.Condition.Field.CC, Rule.Condition.Comparator.CONTAINS, 
"something");
+    private static final Rule.Condition CONDITION = 
Rule.Condition.of(Rule.Condition.FixedField.CC, 
Rule.Condition.Comparator.CONTAINS, "something");
     private static final Rule.Action ACTION = 
Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds("id-01"));
     private static final Rule.Builder RULE_BUILDER = 
Rule.builder().name(NAME).conditionGroup(CONDITION).action(ACTION);
     private static final Rule RULE_1 = 
RULE_BUILDER.id(Rule.Id.of("1")).build();
diff --git 
a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/PopulateFilteringProjectionRequestToTaskTest.java
 
b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/PopulateFilteringProjectionRequestToTaskTest.java
index d3efd1440d..45ef892882 100644
--- 
a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/PopulateFilteringProjectionRequestToTaskTest.java
+++ 
b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/PopulateFilteringProjectionRequestToTaskTest.java
@@ -23,7 +23,7 @@ import static io.restassured.RestAssured.given;
 import static io.restassured.RestAssured.when;
 import static io.restassured.RestAssured.with;
 import static 
org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.CONTAINS;
-import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.SUBJECT;
+import static 
org.apache.james.jmap.api.filtering.Rule.Condition.FixedField.SUBJECT;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org
For additional commands, e-mail: notifications-h...@james.apache.org

Reply via email to