|
1 | 1 | package config |
2 | 2 |
|
3 | | -import "testing" |
| 3 | +import ( |
| 4 | + "strings" |
| 5 | + "testing" |
| 6 | +) |
4 | 7 |
|
5 | 8 | func TestLoadDefaultsToPostgresAndRedis(t *testing.T) { |
6 | 9 | keys := []string{ |
@@ -301,3 +304,63 @@ func TestLoadReadsRedisTLSSettings(t *testing.T) { |
301 | 304 | t.Fatal("Redis.InsecureSkipVerify = false, want true") |
302 | 305 | } |
303 | 306 | } |
| 307 | + |
| 308 | +func TestLoadAcceptsValidDatabaseSchema(t *testing.T) { |
| 309 | + t.Setenv("DATABASE_DRIVER", "") |
| 310 | + t.Setenv("DATABASE_HOST", "postgres") |
| 311 | + t.Setenv("DATABASE_NAME", "postgres") |
| 312 | + t.Setenv("DATABASE_SCHEMA", "codex2api") |
| 313 | + t.Setenv("CACHE_DRIVER", "") |
| 314 | + t.Setenv("REDIS_ADDR", "redis:6379") |
| 315 | + |
| 316 | + cfg, err := Load("__not_exists__.env") |
| 317 | + if err != nil { |
| 318 | + t.Fatalf("Load() 返回错误: %v", err) |
| 319 | + } |
| 320 | + if got := cfg.Database.Schema; got != "codex2api" { |
| 321 | + t.Fatalf("Database.Schema = %q, want codex2api", got) |
| 322 | + } |
| 323 | + dsn := cfg.Database.DSN() |
| 324 | + if !strings.Contains(dsn, "options='-c search_path=codex2api,public'") { |
| 325 | + t.Fatalf("DSN 未包含 search_path 选项: %s", dsn) |
| 326 | + } |
| 327 | +} |
| 328 | + |
| 329 | +func TestLoadRejectsInvalidDatabaseSchema(t *testing.T) { |
| 330 | + cases := []string{ |
| 331 | + "public; DROP TABLE users", |
| 332 | + "with space", |
| 333 | + "1leading-digit", |
| 334 | + "with-dash", |
| 335 | + "中文", |
| 336 | + strings.Repeat("a", 64), |
| 337 | + } |
| 338 | + for _, name := range cases { |
| 339 | + t.Run(name, func(t *testing.T) { |
| 340 | + t.Setenv("DATABASE_DRIVER", "") |
| 341 | + t.Setenv("DATABASE_HOST", "postgres") |
| 342 | + t.Setenv("DATABASE_SCHEMA", name) |
| 343 | + t.Setenv("CACHE_DRIVER", "") |
| 344 | + t.Setenv("REDIS_ADDR", "redis:6379") |
| 345 | + |
| 346 | + if _, err := Load("__not_exists__.env"); err == nil { |
| 347 | + t.Fatalf("非法 schema %q 应当被拒绝,但 Load() 通过了", name) |
| 348 | + } |
| 349 | + }) |
| 350 | + } |
| 351 | +} |
| 352 | + |
| 353 | +func TestDSNOmitsSchemaWhenEmpty(t *testing.T) { |
| 354 | + d := DatabaseConfig{ |
| 355 | + Driver: "postgres", |
| 356 | + Host: "h", |
| 357 | + Port: 5432, |
| 358 | + User: "u", |
| 359 | + Password: "p", |
| 360 | + DBName: "db", |
| 361 | + SSLMode: "disable", |
| 362 | + } |
| 363 | + if got := d.DSN(); strings.Contains(got, "search_path") { |
| 364 | + t.Fatalf("空 schema 时 DSN 不应包含 search_path: %s", got) |
| 365 | + } |
| 366 | +} |
0 commit comments