本次重构实现了标准化的本地配置系统,替换原有的硬编码环境变量读取逻辑: 1. 新增跨平台的原子化配置文件读写,支持Unix和Windows系统 2. 新增init命令用于安全初始化和更新本地凭据 3. 替换原有错误提示文案为更友好的中文提示 4. 更新文档说明新的配置流程和安全规范 5. 新增完整的配置相关测试用例 6. 添加必要的依赖包支持
61 lines
1.6 KiB
Go
61 lines
1.6 KiB
Go
package command
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestInitCommandReadsTokenWithoutPrintingIt(t *testing.T) {
|
|
const token = "test-private-token"
|
|
var receivedToken string
|
|
cmd := newInitCommand(
|
|
func(value string) (string, error) {
|
|
receivedToken = value
|
|
return "/test/repository/.env", nil
|
|
},
|
|
func(input io.Reader, output io.Writer) (string, error) {
|
|
_, _ = io.WriteString(output, "credential prompt")
|
|
return token, nil
|
|
},
|
|
)
|
|
var stdout, stderr bytes.Buffer
|
|
cmd.SetOut(&stdout)
|
|
cmd.SetErr(&stderr)
|
|
if err := cmd.Execute(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if receivedToken != token {
|
|
t.Fatalf("initializer received token=%q", receivedToken)
|
|
}
|
|
if strings.Contains(stdout.String(), token) || strings.Contains(stderr.String(), token) {
|
|
t.Fatal("init output exposed the token")
|
|
}
|
|
result := initResult{}
|
|
if err := json.Unmarshal(stdout.Bytes(), &result); err != nil {
|
|
t.Fatalf("decode init result: %v", err)
|
|
}
|
|
if !result.Initialized || result.EnvFile != "/test/repository/.env" {
|
|
t.Fatalf("result = %#v", result)
|
|
}
|
|
}
|
|
|
|
func TestInitCommandDoesNotExposeForceFlag(t *testing.T) {
|
|
cmd := newInitCommand(func(string) (string, error) {
|
|
return "", nil
|
|
}, func(io.Reader, io.Writer) (string, error) {
|
|
return "token", nil
|
|
})
|
|
if cmd.Flags().Lookup("force") != nil {
|
|
t.Fatal("init still exposes the retired --force flag")
|
|
}
|
|
}
|
|
|
|
func TestInitTerminalReaderRejectsNonTTY(t *testing.T) {
|
|
if _, err := readTokenFromTerminal(bytes.NewBufferString("token\n"), io.Discard); err == nil || !strings.Contains(err.Error(), "交互式终端") {
|
|
t.Fatalf("error = %v", err)
|
|
}
|
|
}
|