package service import ( "os" "path/filepath" "runtime" "strings" "testing" ) func TestFileAISecretStore_原子保存且不回显明文(t *testing.T) { path := filepath.Join(t.TempDir(), "ai-secrets.yaml") store := NewFileAISecretStore(path) const secret = "test-key-not-for-production" if err := store.Set("AI-1", secret); err != nil { t.Fatal(err) } configured, suffix, err := store.Status("AI-1") if err != nil || !configured || !strings.HasSuffix(suffix, "tion") || strings.Contains(suffix, secret) { t.Fatalf("密钥状态不安全: configured=%v suffix=%q err=%v", configured, suffix, err) } raw, err := os.ReadFile(path) if err != nil || !strings.Contains(string(raw), secret) { t.Fatalf("独立密钥文件没有保存测试值: %v", err) } if runtime.GOOS != "windows" { info, _ := os.Stat(path) if info.Mode().Perm() != 0o600 { t.Fatalf("密钥权限 = %o,期望 600", info.Mode().Perm()) } } if err := store.Clear("AI-1"); err != nil { t.Fatal(err) } configured, _, err = store.Status("AI-1") if err != nil || configured { t.Fatalf("清除密钥失败: configured=%v err=%v", configured, err) } } func TestFileAISecretStore_拒绝仓库内和相对路径(t *testing.T) { for _, path := range []string{"relative.yaml", filepath.Join("data", "ai.yaml")} { store := NewFileAISecretStore(path) if err := store.Set("AI-1", "12345678"); err == nil { t.Fatalf("路径 %q 应被拒绝", path) } } }