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

bamaer pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new b9460befd3 fix incorrect log level store, fixes #8603 (#8611)
b9460befd3 is described below

commit b9460befd3a96bc7854faacb396e05fc62e500bd
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Fri Sep 25 17:17:47 2026 +0200

    fix incorrect log level store, fixes #8603 (#8611)
---
 .../transforms/writetolog/WriteToLogDialog.java    |   6 +-
 .../writetolog/WriteToLogDialogTest.java           | 160 +++++++++++++++++++++
 2 files changed, 164 insertions(+), 2 deletions(-)

diff --git 
a/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogDialog.java
 
b/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogDialog.java
index 1fca4077a4..4fbe2c9bc7 100644
--- 
a/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogDialog.java
+++ 
b/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogDialog.java
@@ -322,10 +322,12 @@ public class WriteToLogDialog extends BaseTransformDialog 
{
     input.setLimitRows(wLimitRows.getSelection());
     input.setLimitRowsNumber(Const.toInt(wLimitRowsNumber.getText(), 0));
 
-    if (wLoglevel.getSelectionIndex() < 0) {
+    // The combo holds the translated descriptions in enum order: map by 
position, not by label.
+    int logLevelIndex = wLoglevel.getSelectionIndex();
+    if (logLevelIndex < 0 || logLevelIndex >= LogLevel.values().length) {
       input.setLogLevel(LogLevel.BASIC);
     } else {
-      input.setLogLevel(LogLevel.lookupCode(wLoglevel.getText()));
+      input.setLogLevel(LogLevel.values()[logLevelIndex]);
     }
 
     if (!Utils.isEmpty(wLogMessage.getText())) {
diff --git 
a/plugins/transforms/writetolog/src/test/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogDialogTest.java
 
b/plugins/transforms/writetolog/src/test/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogDialogTest.java
new file mode 100644
index 0000000000..708477854a
--- /dev/null
+++ 
b/plugins/transforms/writetolog/src/test/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogDialogTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.hop.pipeline.transforms.writetolog;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.stream.Stream;
+import org.apache.hop.core.logging.LogLevel;
+import org.apache.hop.core.plugins.PluginRegistry;
+import org.apache.hop.core.plugins.TransformPluginType;
+import org.apache.hop.core.variables.Variables;
+import org.apache.hop.i18n.GlobalMessages;
+import org.apache.hop.pipeline.PipelineMeta;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.apache.hop.ui.testing.SwtBotTestBase;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotCCombo;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/**
+ * SWTBot coverage for the log level combo of {@link WriteToLogDialog} 
(#8603). The combo shows the
+ * translated {@link LogLevel} descriptions, so OK must map the selection back 
by position and never
+ * by label: "Row Level (very detailed)" is not the code "Rowlevel", and in 
most languages none of
+ * the labels match a code at all.
+ *
+ * <p>The descriptions are resolved once per JVM, so the other languages are 
exercised by loading
+ * each shipped translation into the combo before selecting - exactly what the 
dialog shows when Hop
+ * GUI runs in that language.
+ */
+@Tag("uitest")
+class WriteToLogDialogTest extends SwtBotTestBase {
+
+  private static final String TRANSFORM_NAME = "write to log";
+  private static final String SHELL_TITLE = "Write to log";
+  private static final String MESSAGES_PATH =
+      "/org/apache/hop/core/logging/messages/messages_%s.properties";
+  private static final String DEFAULT_LOCALE = "en_US";
+
+  static Stream<String> localeCodes() {
+    return Arrays.stream(GlobalMessages.localeCodes);
+  }
+
+  @ParameterizedTest(name = "{0}")
+  @MethodSource("localeCodes")
+  void okStoresEverySelectedLogLevel(String localeCode) throws IOException {
+    String[] labels = logLevelLabels(localeCode);
+    assertEquals(
+        LogLevel.values().length,
+        Arrays.stream(labels).distinct().count(),
+        "log level labels of "
+            + localeCode
+            + " must be distinguishable: "
+            + Arrays.toString(labels));
+
+    for (LogLevel level : LogLevel.values()) {
+      WriteToLogMeta meta = new WriteToLogMeta();
+      meta.setLogLevel(level == LogLevel.BASIC ? LogLevel.DEBUG : 
LogLevel.BASIC);
+      PipelineMeta pipelineMeta = pipelineWith(meta);
+
+      withDialog(
+          parent -> new WriteToLogDialog(parent, new Variables(), meta, 
pipelineMeta).open(),
+          bot -> {
+            SWTBot dialog = bot.shell(SHELL_TITLE).activate().bot();
+            SWTBotCCombo combo = dialog.ccomboBox(0);
+            assertArrayEquals(
+                LogLevel.getLogLevelDescriptions(),
+                combo.items(),
+                "the combo must list the log level descriptions in enum 
order");
+
+            display.syncExec(() -> combo.widget.setItems(labels));
+            combo.setSelection(level.ordinal());
+            assertEquals(labels[level.ordinal()], combo.getText());
+
+            dialog.button(buttonLabel("System.Button.OK")).click();
+          });
+
+      assertEquals(
+          level,
+          meta.getLogLevel(),
+          "selecting '" + labels[level.ordinal()] + "' (" + localeCode + ") 
must store " + level);
+    }
+  }
+
+  @Test
+  void reopeningShowsTheStoredLogLevel() {
+    for (LogLevel level : LogLevel.values()) {
+      WriteToLogMeta meta = new WriteToLogMeta();
+      meta.setLogLevel(level);
+      PipelineMeta pipelineMeta = pipelineWith(meta);
+
+      withDialog(
+          parent -> new WriteToLogDialog(parent, new Variables(), meta, 
pipelineMeta).open(),
+          bot -> {
+            SWTBot dialog = bot.shell(SHELL_TITLE).activate().bot();
+            assertEquals(level.getDescription(), 
dialog.ccomboBox(0).getText());
+            dialog.button(buttonLabel("System.Button.OK")).click();
+          });
+
+      assertEquals(level, meta.getLogLevel(), "OK without changes must keep " 
+ level);
+    }
+  }
+
+  /**
+   * The log level labels a Hop GUI running in the given language shows, in 
enum order. Keys a
+   * translation lacks fall back to en_US, like {@code BaseMessages} does.
+   */
+  private static String[] logLevelLabels(String localeCode) throws IOException 
{
+    Properties fallback = loadMessages(DEFAULT_LOCALE);
+    Properties messages = loadMessages(localeCode);
+    return Arrays.stream(LogLevel.values())
+        .map(level -> "LogWriter.Level." + level.getCode() + ".LongDesc")
+        .map(key -> messages.getProperty(key, fallback.getProperty(key)))
+        .toArray(String[]::new);
+  }
+
+  private static Properties loadMessages(String localeCode) throws IOException 
{
+    Properties properties = new Properties();
+    try (InputStream in =
+        LogLevel.class.getResourceAsStream(String.format(MESSAGES_PATH, 
localeCode))) {
+      if (in != null) {
+        properties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
+      }
+    }
+    return properties;
+  }
+
+  private static PipelineMeta pipelineWith(WriteToLogMeta meta) {
+    String pluginId = 
PluginRegistry.getInstance().getPluginId(TransformPluginType.class, meta);
+    assertNotNull(pluginId, "Write to log transform plugin must be 
registered");
+    PipelineMeta pipelineMeta = new PipelineMeta();
+    pipelineMeta.addTransform(new TransformMeta(pluginId, TRANSFORM_NAME, 
meta));
+    return pipelineMeta;
+  }
+}

Reply via email to