gnodet commented on code in PR #22285:
URL: https://github.com/apache/camel/pull/22285#discussion_r2994983412


##########
components/camel-google/camel-google-mail/src/main/java/org/apache/camel/component/google/mail/transform/GoogleMailUpdateMessageLabelsDataTypeTransformer.java:
##########
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.google.mail.transform;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.api.services.gmail.Gmail;
+import com.google.api.services.gmail.model.Label;
+import com.google.api.services.gmail.model.ListLabelsResponse;
+import com.google.api.services.gmail.model.ModifyMessageRequest;
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.google.mail.GoogleMailComponent;
+import org.apache.camel.component.google.mail.internal.GoogleMailConstants;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.Transformer;
+
+/**
+ * Data type transformer that builds a {@link ModifyMessageRequest} that 
updates labels of a message from exchange
+ * variables {@code addLabels} and {@code removeLabels} .
+ *
+ */
+@DataTypeTransformer(name = "google-mail:update-message-labels",
+                     description = "Updates Gmail message labels by resolving 
label names from addLabels/removeLabels exchange variables")
+public class GoogleMailUpdateMessageLabelsDataTypeTransformer extends 
Transformer {
+
+    public static final String VARIABLE_ADD_LABELS = "addLabels";
+    public static final String VARIABLE_REMOVE_LABELS = "removeLabels";
+
+    private static final String DEFAULT_USER_ID = "me";
+    private static final String HEADER_USER_ID = 
GoogleMailConstants.PROPERTY_PREFIX + "userId";
+
+    private volatile Map<String, String> labelNameToIdCache;
+
+    @Override
+    public void transform(Message message, DataType fromType, DataType toType) 
throws Exception {
+        Exchange exchange = message.getExchange();
+
+        List<String> addLabelNames = getLabelsVariable(exchange, 
VARIABLE_ADD_LABELS);
+        List<String> removeLabelNames = getLabelsVariable(exchange, 
VARIABLE_REMOVE_LABELS);
+
+        if (addLabelNames.isEmpty() && removeLabelNames.isEmpty()) {
+            throw new CamelExecutionException(
+                    "At least one of 'addLabels' or 'removeLabels' exchange 
variables must be set", exchange);
+        }
+
+        String userId = message.getHeader(HEADER_USER_ID, DEFAULT_USER_ID, 
String.class);
+        Map<String, String> labelMap = getLabelMap(userId);
+
+        List<String> addLabelIds = resolveLabelIds(addLabelNames, labelMap, 
exchange);
+        List<String> removeLabelIds = resolveLabelIds(removeLabelNames, 
labelMap, exchange);
+
+        ModifyMessageRequest request = new ModifyMessageRequest();
+        if (!addLabelIds.isEmpty()) {
+            request.setAddLabelIds(addLabelIds);
+        }
+        if (!removeLabelIds.isEmpty()) {
+            request.setRemoveLabelIds(removeLabelIds);
+        }
+
+        message.setBody(request);
+    }
+
+    @SuppressWarnings("unchecked")
+    private List<String> getLabelsVariable(Exchange exchange, String 
variableName) {
+        Object value = exchange.getVariable(variableName);
+        if (value == null) {
+            return Collections.emptyList();
+        }
+        if (value instanceof List) {
+            return (List<String>) value;
+        }
+        if (value instanceof String stringValue) {
+            if (stringValue.isBlank()) {
+                return Collections.emptyList();
+            }
+            return Arrays.asList(stringValue.split(","));
+        }
+        throw new CamelExecutionException(
+                "Exchange variable '" + variableName + "' must be a 
List<String> or a comma-separated String, but was: "
+                                          + value.getClass().getName(),
+                exchange);
+    }
+
+    private List<String> resolveLabelIds(List<String> labelNames, Map<String, 
String> labelMap, Exchange exchange) {
+        List<String> ids = new ArrayList<>(labelNames.size());
+        for (String name : labelNames) {
+            String id = labelMap.get(name);
+            if (id == null) {
+                throw new CamelExecutionException(
+                        "Label '" + name + "' not found. Available labels: " + 
labelMap.keySet(), exchange);
+            }
+            ids.add(id);
+        }
+        return ids;
+    }
+
+    private Map<String, String> getLabelMap(String userId) throws Exception {
+        if (labelNameToIdCache != null) {
+            return labelNameToIdCache;
+        }
+        synchronized (this) {
+            if (labelNameToIdCache != null) {
+                return labelNameToIdCache;
+            }
+            labelNameToIdCache = 
Collections.unmodifiableMap(fetchLabelMap(userId));
+            return labelNameToIdCache;
+        }
+    }

Review Comment:
   Two observations about the label cache:
   
   1. **Cache ignores `userId`** — The cache is populated using whichever 
`userId` arrives first (typically `"me"`). If a later message uses a different 
`userId` header, it silently gets the wrong user's labels. Gmail labels are 
per-user, so custom labels from user A would be returned for user B. If 
multi-user support is out of scope, I'd suggest documenting that assumption 
explicitly.
   
   2. **No cache invalidation** — Labels created, renamed, or deleted while 
Camel is running won't be reflected until restart. For a first version this may 
be acceptable, but it should be documented. An alternative would be to drop the 
cache entirely — resolving labels is a cheap API call and label modifications 
are typically infrequent.



##########
components/camel-google/camel-google-mail/src/main/docs/google-mail-component.adoc:
##########
@@ -63,6 +63,84 @@ include::partial$component-endpoint-options.adoc[]
 include::partial$component-endpoint-headers.adoc[]
 // component options: END
 
+== Data Type Transformer: update-message-labels
+
+The `google-mail:update-message-labels` data type transformer builds a 
`ModifyMessageRequest` from exchange variables, resolving label names to Gmail 
label IDs automatically.
+
+This is useful for modifying Gmail message labels (categorizing, archiving, 
starring, moving, etc.) without manually calling the labels/list API.
+
+=== Exchange Variables
+
+[cols="1,1,3"]
+|===
+| Variable | Type | Description
+
+| `addLabels`
+| `String` (comma-separated) or `List<String>`
+| Label names to add to the message.
+
+| `removeLabels`
+| `String` (comma-separated) or `List<String>`
+| Label names to remove from the message.
+|===
+
+At least one of the two variables must be set.
+
+Both system labels (INBOX, UNREAD, STARRED, SPAM, TRASH, IMPORTANT, etc.) and 
custom user-defined labels are resolved via the Gmail labels/list API.
+
+=== Examples
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("google-mail-stream:0")
+    .setVariable("addLabels", constant("Work"))
+    .setVariable("removeLabels", constant("INBOX,UNREAD"))
+    .transformDataType(new DataType("google-mail:update-message-labels"))
+    .to("google-mail:messages/modify");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: "google-mail-stream:0"
+    steps:
+      - setVariable:
+          name: addLabels
+          constant: "Work"
+      - setVariable:
+          name: removeLabels
+          constant: "INBOX,UNREAD"
+      - transformDataType:

Review Comment:
   Minor: `toType` is indented 4 spaces from `transformDataType`, but the rest 
of the YAML example uses 2-space indentation (e.g., 
`setVariable`/`name`/`constant` above).
   
   ```suggestion
         - transformDataType:
             toType: "google-mail:update-message-labels"
   ```



##########
components/camel-google/camel-google-mail/src/test/java/org/apache/camel/component/google/mail/transform/GoogleMailUpdateMessageLabelsDataTypeTransformerTest.java:
##########
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.google.mail.transform;
+
+import java.util.List;
+
+import com.google.api.services.gmail.model.ModifyMessageRequest;
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.google.mail.GoogleMailComponent;
+import org.apache.camel.component.google.mail.GoogleMailConfiguration;
+import org.apache.camel.component.google.mail.MockGoogleMailClientFactory;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+class GoogleMailUpdateMessageLabelsDataTypeTransformerTest extends 
CamelTestSupport {
+
+    private static final String LABELS_RESPONSE = """
+            {
+              "labels": [
+                {"id": "INBOX", "name": "INBOX"},
+                {"id": "UNREAD", "name": "UNREAD"},
+                {"id": "Label_789", "name": "Work"},
+                {"id": "Label_456", "name": "Another Label"}
+              ]
+            }
+            """;
+
+    private GoogleMailUpdateMessageLabelsDataTypeTransformer transformer;
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        final CamelContext context = new DefaultCamelContext();
+
+        GoogleMailConfiguration configuration = new GoogleMailConfiguration();
+        configuration.setClientId("mock-client-id");
+        configuration.setClientSecret("mock-client-secret");
+        configuration.setApplicationName("mock");
+
+        final GoogleMailComponent component = new GoogleMailComponent(context);
+        component.setConfiguration(configuration);
+        component.setClientFactory(new 
MockGoogleMailClientFactory(LABELS_RESPONSE));
+
+        context.addComponent("google-mail", component);
+
+        return context;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:input")
+                        .transformDataType("google-mail:update-message-labels")
+                        .to("mock:result");
+            }
+        };
+    }
+
+    @Override
+    protected void doPostSetup() {
+        transformer = new GoogleMailUpdateMessageLabelsDataTypeTransformer();
+        transformer.setCamelContext(context);
+    }
+
+    @Test
+    void testAddAndRemoveLabels() throws Exception {
+        Exchange exchange = new DefaultExchange(context);
+        exchange.setVariable("addLabels", List.of("Work"));
+        exchange.setVariable("removeLabels", List.of("INBOX"));
+
+        transformer.transform(exchange.getMessage(), DataType.ANY, 
DataType.ANY);
+
+        ModifyMessageRequest request = 
exchange.getMessage().getBody(ModifyMessageRequest.class);
+        assertNotNull(request);
+        assertEquals(List.of("Label_789"), request.getAddLabelIds());
+        assertEquals(List.of("INBOX"), request.getRemoveLabelIds());
+    }
+
+    @Test
+    void testCommaSeparatedString() throws Exception {
+        Exchange exchange = new DefaultExchange(context);
+        exchange.setVariable("addLabels", "Work,Another Label");
+        exchange.setVariable("removeLabels", "INBOX");
+
+        transformer.transform(exchange.getMessage(), DataType.ANY, 
DataType.ANY);
+
+        ModifyMessageRequest request = 
exchange.getMessage().getBody(ModifyMessageRequest.class);
+        assertNotNull(request);
+        assertEquals(List.of("Label_789", "Label_456"), 
request.getAddLabelIds());
+        assertEquals(List.of("INBOX"), request.getRemoveLabelIds());
+    }
+
+    @Test
+    void testOnlyAddLabels() throws Exception {
+        Exchange exchange = new DefaultExchange(context);
+        exchange.setVariable("addLabels", List.of("Work"));
+
+        transformer.transform(exchange.getMessage(), DataType.ANY, 
DataType.ANY);
+
+        ModifyMessageRequest request = 
exchange.getMessage().getBody(ModifyMessageRequest.class);
+        assertNotNull(request);
+        assertEquals(List.of("Label_789"), request.getAddLabelIds());
+        assertNull(request.getRemoveLabelIds());
+    }
+

Review Comment:
   Nit: there's `testOnlyAddLabels` but no symmetric `testOnlyRemoveLabels`. 
The code handles it correctly, but having the test would explicitly document 
that behavior.



##########
components/camel-google/camel-google-mail/src/main/java/org/apache/camel/component/google/mail/transform/GoogleMailUpdateMessageLabelsDataTypeTransformer.java:
##########
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.google.mail.transform;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.api.services.gmail.Gmail;
+import com.google.api.services.gmail.model.Label;
+import com.google.api.services.gmail.model.ListLabelsResponse;
+import com.google.api.services.gmail.model.ModifyMessageRequest;
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.google.mail.GoogleMailComponent;
+import org.apache.camel.component.google.mail.internal.GoogleMailConstants;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.Transformer;
+
+/**
+ * Data type transformer that builds a {@link ModifyMessageRequest} that 
updates labels of a message from exchange
+ * variables {@code addLabels} and {@code removeLabels} .
+ *
+ */
+@DataTypeTransformer(name = "google-mail:update-message-labels",
+                     description = "Updates Gmail message labels by resolving 
label names from addLabels/removeLabels exchange variables")
+public class GoogleMailUpdateMessageLabelsDataTypeTransformer extends 
Transformer {
+
+    public static final String VARIABLE_ADD_LABELS = "addLabels";
+    public static final String VARIABLE_REMOVE_LABELS = "removeLabels";
+
+    private static final String DEFAULT_USER_ID = "me";
+    private static final String HEADER_USER_ID = 
GoogleMailConstants.PROPERTY_PREFIX + "userId";
+
+    private volatile Map<String, String> labelNameToIdCache;
+
+    @Override
+    public void transform(Message message, DataType fromType, DataType toType) 
throws Exception {
+        Exchange exchange = message.getExchange();
+
+        List<String> addLabelNames = getLabelsVariable(exchange, 
VARIABLE_ADD_LABELS);
+        List<String> removeLabelNames = getLabelsVariable(exchange, 
VARIABLE_REMOVE_LABELS);
+
+        if (addLabelNames.isEmpty() && removeLabelNames.isEmpty()) {
+            throw new CamelExecutionException(
+                    "At least one of 'addLabels' or 'removeLabels' exchange 
variables must be set", exchange);
+        }
+
+        String userId = message.getHeader(HEADER_USER_ID, DEFAULT_USER_ID, 
String.class);
+        Map<String, String> labelMap = getLabelMap(userId);
+
+        List<String> addLabelIds = resolveLabelIds(addLabelNames, labelMap, 
exchange);
+        List<String> removeLabelIds = resolveLabelIds(removeLabelNames, 
labelMap, exchange);
+
+        ModifyMessageRequest request = new ModifyMessageRequest();
+        if (!addLabelIds.isEmpty()) {
+            request.setAddLabelIds(addLabelIds);
+        }
+        if (!removeLabelIds.isEmpty()) {
+            request.setRemoveLabelIds(removeLabelIds);
+        }
+
+        message.setBody(request);
+    }
+
+    @SuppressWarnings("unchecked")
+    private List<String> getLabelsVariable(Exchange exchange, String 
variableName) {
+        Object value = exchange.getVariable(variableName);
+        if (value == null) {
+            return Collections.emptyList();
+        }
+        if (value instanceof List) {
+            return (List<String>) value;
+        }
+        if (value instanceof String stringValue) {
+            if (stringValue.isBlank()) {
+                return Collections.emptyList();
+            }
+            return Arrays.asList(stringValue.split(","));

Review Comment:
   Users will naturally write `"Work, INBOX"` (with a space after the comma), 
but `split(",")` preserves whitespace: `" INBOX"` won't match label `"INBOX"`.
   
   ```suggestion
               return 
Arrays.stream(stringValue.split(",")).map(String::trim).toList();
   ```
   
   Side note: Gmail allows commas in label names (e.g., `"Work, Personal"`). 
The comma-separated format would incorrectly split such names. Users can work 
around this by using `List<String>` instead — might be worth mentioning in the 
docs.



##########
components/camel-google/camel-google-mail/src/test/java/org/apache/camel/component/google/mail/transform/GoogleMailUpdateMessageLabelsDataTypeTransformerTest.java:
##########
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.google.mail.transform;
+
+import java.util.List;
+
+import com.google.api.services.gmail.model.ModifyMessageRequest;
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.google.mail.GoogleMailComponent;
+import org.apache.camel.component.google.mail.GoogleMailConfiguration;
+import org.apache.camel.component.google.mail.MockGoogleMailClientFactory;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+class GoogleMailUpdateMessageLabelsDataTypeTransformerTest extends 
CamelTestSupport {
+
+    private static final String LABELS_RESPONSE = """
+            {
+              "labels": [
+                {"id": "INBOX", "name": "INBOX"},
+                {"id": "UNREAD", "name": "UNREAD"},
+                {"id": "Label_789", "name": "Work"},
+                {"id": "Label_456", "name": "Another Label"}
+              ]
+            }
+            """;
+
+    private GoogleMailUpdateMessageLabelsDataTypeTransformer transformer;
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        final CamelContext context = new DefaultCamelContext();
+
+        GoogleMailConfiguration configuration = new GoogleMailConfiguration();
+        configuration.setClientId("mock-client-id");
+        configuration.setClientSecret("mock-client-secret");
+        configuration.setApplicationName("mock");
+
+        final GoogleMailComponent component = new GoogleMailComponent(context);
+        component.setConfiguration(configuration);
+        component.setClientFactory(new 
MockGoogleMailClientFactory(LABELS_RESPONSE));
+
+        context.addComponent("google-mail", component);
+
+        return context;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:input")
+                        .transformDataType("google-mail:update-message-labels")
+                        .to("mock:result");
+            }
+        };
+    }
+
+    @Override
+    protected void doPostSetup() {
+        transformer = new GoogleMailUpdateMessageLabelsDataTypeTransformer();
+        transformer.setCamelContext(context);
+    }
+
+    @Test
+    void testAddAndRemoveLabels() throws Exception {
+        Exchange exchange = new DefaultExchange(context);
+        exchange.setVariable("addLabels", List.of("Work"));
+        exchange.setVariable("removeLabels", List.of("INBOX"));
+
+        transformer.transform(exchange.getMessage(), DataType.ANY, 
DataType.ANY);
+
+        ModifyMessageRequest request = 
exchange.getMessage().getBody(ModifyMessageRequest.class);
+        assertNotNull(request);
+        assertEquals(List.of("Label_789"), request.getAddLabelIds());
+        assertEquals(List.of("INBOX"), request.getRemoveLabelIds());
+    }
+
+    @Test
+    void testCommaSeparatedString() throws Exception {
+        Exchange exchange = new DefaultExchange(context);
+        exchange.setVariable("addLabels", "Work,Another Label");
+        exchange.setVariable("removeLabels", "INBOX");
+
+        transformer.transform(exchange.getMessage(), DataType.ANY, 
DataType.ANY);
+
+        ModifyMessageRequest request = 
exchange.getMessage().getBody(ModifyMessageRequest.class);
+        assertNotNull(request);
+        assertEquals(List.of("Label_789", "Label_456"), 
request.getAddLabelIds());
+        assertEquals(List.of("INBOX"), request.getRemoveLabelIds());
+    }
+
+    @Test
+    void testOnlyAddLabels() throws Exception {
+        Exchange exchange = new DefaultExchange(context);
+        exchange.setVariable("addLabels", List.of("Work"));
+
+        transformer.transform(exchange.getMessage(), DataType.ANY, 
DataType.ANY);
+
+        ModifyMessageRequest request = 
exchange.getMessage().getBody(ModifyMessageRequest.class);
+        assertNotNull(request);
+        assertEquals(List.of("Label_789"), request.getAddLabelIds());
+        assertNull(request.getRemoveLabelIds());
+    }
+
+    @Test
+    void testNoLabelsThrowsException() {
+        Exchange exchange = new DefaultExchange(context);
+
+        assertThrows(CamelExecutionException.class,
+                () -> transformer.transform(exchange.getMessage(), 
DataType.ANY, DataType.ANY));
+    }
+
+    @Test
+    void testUnknownLabelThrowsException() {
+        Exchange exchange = new DefaultExchange(context);
+        exchange.setVariable("addLabels", List.of("NonExistentLabel"));
+
+        assertThrows(CamelExecutionException.class,
+                () -> transformer.transform(exchange.getMessage(), 
DataType.ANY, DataType.ANY));
+    }
+
+    @Test
+    void testExplicitUserId() throws Exception {
+        Exchange exchange = new DefaultExchange(context);
+        exchange.getMessage().setHeader("CamelGoogleMail.userId", 
"[email protected]");
+        exchange.setVariable("addLabels", List.of("Work"));
+
+        transformer.transform(exchange.getMessage(), DataType.ANY, 
DataType.ANY);
+
+        ModifyMessageRequest request = 
exchange.getMessage().getBody(ModifyMessageRequest.class);
+        assertNotNull(request);
+        assertEquals(List.of("Label_789"), request.getAddLabelIds());
+    }
+

Review Comment:
   This test doesn't fully verify that the `userId` header is forwarded to the 
Gmail API. Two things mask the behavior:
   1. The `MockHttpTransport` returns the same response regardless of the 
request URL (which embeds the userId)
   2. With `@TestInstance(PER_CLASS)`, the label cache was already populated by 
earlier tests (using `"me"`)
   
   So this test passes even if the userId header is completely ignored. A 
URL-capturing mock (or resetting the transformer's cache between tests) would 
be needed to verify the userId actually flows through.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to