From 1111991a9c3675f53b64d16379727b2aa6149997 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期一, 28 九月 2026 15:48:08 +0800
Subject: [PATCH] 厂商库口令改为优先读本地凭据文件,并在启动时自检

---
 battery-device-neware/src/test/java/com/battery/device/neware/NewareMysqlAdapterContractTest.java |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/battery-device-neware/src/test/java/com/battery/device/neware/NewareMysqlAdapterContractTest.java b/battery-device-neware/src/test/java/com/battery/device/neware/NewareMysqlAdapterContractTest.java
index d3be22c..14673a6 100644
--- a/battery-device-neware/src/test/java/com/battery/device/neware/NewareMysqlAdapterContractTest.java
+++ b/battery-device-neware/src/test/java/com/battery/device/neware/NewareMysqlAdapterContractTest.java
@@ -220,4 +220,64 @@
             assertTrue(failure.getMessage().contains(account));
         }
     }
+
+    /**
+     * 口令取值顺序:本地凭据文件 → 环境变量 → 启动参数;
+     * 三者都没有时失败信息同时点名文件路径与键名,使"忘了放口令"是可见的失败。
+     */
+    @Test
+    void credentialPrefersTheLocalFileThenEnvironmentThenStartupParameter() throws Exception
+    {
+        java.nio.file.Path directory = java.nio.file.Files.createTempDirectory("vendor-credentials");
+        java.nio.file.Path file = directory.resolve("vendor-credentials.properties");
+        String key = "BATTERY_VENDOR_DB_PASSWORD";
+        try
+        {
+            // 文件、环境变量、启动参数都在时取文件。
+            java.nio.file.Files.writeString(file, key + "=from-file\n");
+            assertEquals("from-file", NewareMysqlAdapterFactory.credential(key, file,
+                    Map.of(key, "from-env"), name -> "from-parameter"));
+
+            // 没有文件时退到环境变量。
+            java.nio.file.Files.delete(file);
+            assertEquals("from-env", NewareMysqlAdapterFactory.credential(key, file,
+                    Map.of(key, "from-env"), name -> "from-parameter"));
+
+            // 前两者都没有时退到启动参数。
+            assertEquals("from-parameter", NewareMysqlAdapterFactory.credential(key, file,
+                    Map.of(), name -> "from-parameter"));
+
+            // 三者都没有:失败信息里同时出现文件路径与键名。
+            var failure = org.junit.jupiter.api.Assertions.assertThrows(
+                    com.battery.device.api.DeviceAdapterException.class,
+                    () -> NewareMysqlAdapterFactory.credential(key, file, Map.of(), name -> null));
+            assertTrue(failure.getMessage().contains(file.toString()));
+            assertTrue(failure.getMessage().contains(key));
+        }
+        finally
+        {
+            java.nio.file.Files.deleteIfExists(file);
+            java.nio.file.Files.deleteIfExists(directory);
+        }
+    }
+
+    /** 凭据文件里的空白值不算配置过:否则一个空模板会把失败推到连接阶段。 */
+    @Test
+    void blankCredentialInTheFileIsTreatedAsMissing() throws Exception
+    {
+        java.nio.file.Path directory = java.nio.file.Files.createTempDirectory("vendor-credentials-blank");
+        java.nio.file.Path file = directory.resolve("vendor-credentials.properties");
+        String key = "BATTERY_VENDOR_DB_PASSWORD";
+        try
+        {
+            java.nio.file.Files.writeString(file, key + "=\n");
+            assertEquals("from-env", NewareMysqlAdapterFactory.credential(key, file, Map.of(key, "from-env"),
+                    name -> null));
+        }
+        finally
+        {
+            java.nio.file.Files.deleteIfExists(file);
+            java.nio.file.Files.deleteIfExists(directory);
+        }
+    }
 }

--
Gitblit v1.7.1