| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- package config
- import (
- "strings"
- "testing"
- )
- // setAll 设置一组完整的必填环境变量,供各用例在此基础上调整。
- func setAll(t *testing.T) {
- t.Helper()
- t.Setenv("HAVEN_LISTEN_ADDR", "127.0.0.1:8080")
- t.Setenv("HAVEN_DB_DSN", "postgres://haven@127.0.0.1:5432/haven?sslmode=disable")
- t.Setenv("HAVEN_FRONTEND_DIR", "/opt/haven/frontend/dist")
- t.Setenv("HAVEN_GOGS_BASE_URL", "https://gogs.example.com")
- t.Setenv("HAVEN_COOKIE_DOMAIN", "app.example.com")
- }
- func TestLoadDefaults(t *testing.T) {
- setAll(t)
- cfg, err := Load()
- if err != nil {
- t.Fatalf("Load() 返回错误: %v", err)
- }
- if !cfg.CookieSecure {
- t.Error("HAVEN_COOKIE_SECURE 未设置时应默认 true")
- }
- if cfg.TotpIssuer != "Haven" {
- t.Errorf("HAVEN_TOTP_ISSUER 默认为 Haven,实际 %q", cfg.TotpIssuer)
- }
- if cfg.LogLevel != "info" {
- t.Errorf("HAVEN_LOG_LEVEL 默认为 info,实际 %q", cfg.LogLevel)
- }
- }
- func TestLoadMissingRequired(t *testing.T) {
- setAll(t)
- t.Setenv("HAVEN_DB_DSN", "")
- t.Setenv("HAVEN_COOKIE_DOMAIN", " ")
- _, err := Load()
- if err == nil {
- t.Fatal("缺少必填项时应返回错误")
- }
- // 应一次性列出全部缺失项,而不是只报第一个
- for _, name := range []string{"HAVEN_DB_DSN", "HAVEN_COOKIE_DOMAIN"} {
- if !strings.Contains(err.Error(), name) {
- t.Errorf("错误信息应包含 %s,实际 %q", name, err.Error())
- }
- }
- }
- func TestLoadCookieSecureFalse(t *testing.T) {
- setAll(t)
- t.Setenv("HAVEN_COOKIE_SECURE", "false")
- cfg, err := Load()
- if err != nil {
- t.Fatalf("Load() 返回错误: %v", err)
- }
- if cfg.CookieSecure {
- t.Error("HAVEN_COOKIE_SECURE=false 时应为 false")
- }
- }
- func TestLoadInvalidCookieSecure(t *testing.T) {
- setAll(t)
- t.Setenv("HAVEN_COOKIE_SECURE", "yes-please")
- if _, err := Load(); err == nil {
- t.Fatal("非法的 HAVEN_COOKIE_SECURE 应返回错误")
- }
- }
- func TestLoadLogLevel(t *testing.T) {
- cases := []struct {
- raw string
- want string
- wantErr bool
- }{
- {raw: "", want: "info"},
- {raw: "DEBUG", want: "debug"},
- {raw: "warn", want: "warn"},
- {raw: "error", want: "error"},
- {raw: "verbose", wantErr: true},
- }
- for _, tc := range cases {
- t.Run(tc.raw, func(t *testing.T) {
- setAll(t)
- t.Setenv("HAVEN_LOG_LEVEL", tc.raw)
- cfg, err := Load()
- if tc.wantErr {
- if err == nil {
- t.Fatalf("HAVEN_LOG_LEVEL=%q 应返回错误", tc.raw)
- }
- return
- }
- if err != nil {
- t.Fatalf("Load() 返回错误: %v", err)
- }
- if cfg.LogLevel != tc.want {
- t.Errorf("HAVEN_LOG_LEVEL=%q 解析为 %q,期望 %q", tc.raw, cfg.LogLevel, tc.want)
- }
- })
- }
- }
- func TestLoadTrimsTrailingSlash(t *testing.T) {
- setAll(t)
- t.Setenv("HAVEN_GOGS_BASE_URL", "https://gogs.example.com/")
- cfg, err := Load()
- if err != nil {
- t.Fatalf("Load() 返回错误: %v", err)
- }
- // 作品集 URL 由 GogsBaseURL + "/" + repo_path 拼接,末尾斜杠必须去掉
- if cfg.GogsBaseURL != "https://gogs.example.com" {
- t.Errorf("GogsBaseURL 应去掉末尾斜杠,实际 %q", cfg.GogsBaseURL)
- }
- }
|