ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
web / web (push) Waiting to run
docs / links (push) Canceled after 0s
detections / detections (push) Canceled after 0s
106 lines
3.1 KiB
Go
106 lines
3.1 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// hasHan reports whether s contains a CJK Han ideograph (the Chinese source text
|
|
// we are replacing). Hangul and ASCII identifiers must survive; Han must not.
|
|
func hasHan(s string) bool {
|
|
for _, r := range s {
|
|
if r >= 0x4e00 && r <= 0x9fff {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func hasHangul(s string) bool {
|
|
for _, r := range s {
|
|
if r >= 0xac00 && r <= 0xd7a3 {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func assertKorean(t *testing.T, label, s string) {
|
|
t.Helper()
|
|
if hasHan(s) {
|
|
t.Errorf("%s: Chinese Han ideograph remains: %q", label, s)
|
|
}
|
|
if !hasHangul(s) {
|
|
t.Errorf("%s: no Hangul found (expected Korean): %q", label, s)
|
|
}
|
|
}
|
|
|
|
// TestPostgresDSNErrorLocalized pins the install-path startup message to Korean.
|
|
// When neither ARTEX_PG_DSN nor a config file supplies a database, PostgresDSN
|
|
// returns an error that propagates verbatim (db.DSN → server.NewManager → the
|
|
// `log.Fatalf("open stores: %v", err)` in cmd/artex/main.go). An operator who
|
|
// boots with missing config sees it first, so it must read as Korean.
|
|
func TestPostgresDSNErrorLocalized(t *testing.T) {
|
|
dir := t.TempDir()
|
|
t.Setenv("ARTEX_PG_DSN", "")
|
|
t.Setenv("ARTEX_CONFIG", filepath.Join(dir, "nope.json"))
|
|
|
|
_, _, err := PostgresDSN()
|
|
if err == nil {
|
|
t.Fatal("missing config should error")
|
|
}
|
|
assertKorean(t, "startup error", err.Error())
|
|
|
|
// The identifiers an operator must act on stay verbatim (not translated).
|
|
for _, want := range []string{"ARTEX_PG_DSN", "database", "dsn", "host/user/dbname"} {
|
|
if !strings.Contains(err.Error(), want) {
|
|
t.Errorf("startup error should keep identifier %q verbatim: %q", want, err.Error())
|
|
}
|
|
}
|
|
|
|
// What the operator actually sees after propagation (no %w wrapping anywhere
|
|
// on the path), recorded so the message can be eyeballed in context.
|
|
t.Logf("open stores: %v", err)
|
|
}
|
|
|
|
// TestPostgresDSNSourceLocalized pins the three source labels (logged at
|
|
// server/manager.go:361) to Korean. They live in the same function as the
|
|
// startup error, so they are localized together to avoid a mixed-language file.
|
|
func TestPostgresDSNSourceLocalized(t *testing.T) {
|
|
dir := t.TempDir()
|
|
cfgPath := filepath.Join(dir, "config.json")
|
|
|
|
// env source
|
|
t.Setenv("ARTEX_CONFIG", filepath.Join(dir, "nope.json"))
|
|
t.Setenv("ARTEX_PG_DSN", "postgres://envwins/x")
|
|
if _, source, err := PostgresDSN(); err != nil {
|
|
t.Fatalf("env source: %v", err)
|
|
} else {
|
|
assertKorean(t, "env source", source)
|
|
}
|
|
|
|
// config file dsn source
|
|
t.Setenv("ARTEX_PG_DSN", "")
|
|
if err := os.WriteFile(cfgPath, []byte(`{"database":{"dsn":"postgres://full/dsn"}}`), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Setenv("ARTEX_CONFIG", cfgPath)
|
|
if _, source, err := PostgresDSN(); err != nil {
|
|
t.Fatalf("dsn source: %v", err)
|
|
} else {
|
|
assertKorean(t, "dsn source", source)
|
|
}
|
|
|
|
// config file fields source
|
|
if err := os.WriteFile(cfgPath, []byte(`{"database":{"host":"10.1.2.3","dbname":"d","user":"u"}}`), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, source, err := PostgresDSN(); err != nil {
|
|
t.Fatalf("fields source: %v", err)
|
|
} else {
|
|
assertKorean(t, "fields source", source)
|
|
}
|
|
}
|