Garmin auth/sync routes move under /api/garmin/*; sync.Service becomes garmin.Sync with garmin.SyncConfig/ClientConfig; applog becomes internal/log; the test mock moves into the garmin package as MockClient (breaking the test-only import cycle the merge created); stale test URLs and type names updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
80 lines
2.4 KiB
Go
80 lines
2.4 KiB
Go
package config
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestLoadApp(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
overrides map[string]string
|
|
want time.Duration
|
|
wantErr string
|
|
}{
|
|
{name: "defaults when no overrides", overrides: nil, want: 720 * time.Hour},
|
|
{name: "override applied", overrides: map[string]string{"session.duration": "168"}, want: 168 * time.Hour},
|
|
{name: "invalid stored value", overrides: map[string]string{"session.duration": "zero"}, wantErr: "session.duration"},
|
|
{name: "unknown stored key", overrides: map[string]string{"bogus.key": "1"}, wantErr: "unknown configuration key"},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := LoadApp(tt.overrides)
|
|
if tt.wantErr != "" {
|
|
if err == nil || !strings.Contains(err.Error(), tt.wantErr) {
|
|
t.Fatalf("err = %v, want containing %q", err, tt.wantErr)
|
|
}
|
|
return
|
|
}
|
|
if err != nil {
|
|
t.Fatalf("LoadApp: %v", err)
|
|
}
|
|
if got.SessionDuration != tt.want {
|
|
t.Fatalf("SessionDuration = %v, want %v", got.SessionDuration, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateAppValue(t *testing.T) {
|
|
if err := ValidateAppValue("session.duration", "24"); err != nil {
|
|
t.Fatalf("valid value rejected: %v", err)
|
|
}
|
|
if err := ValidateAppValue("session.duration", "-1"); err == nil {
|
|
t.Fatal("negative hours accepted")
|
|
}
|
|
if err := ValidateAppValue("session.duration", "1.5"); err == nil {
|
|
t.Fatal("non-integer accepted")
|
|
}
|
|
if err := ValidateAppValue("nope", "1"); err == nil {
|
|
t.Fatal("unknown key accepted")
|
|
}
|
|
}
|
|
|
|
func TestDisplayEnv_MasksSecrets(t *testing.T) {
|
|
cfg := EnvConfig{
|
|
BackendAddr: ":8080", OIDCClientSecret: "hunter2",
|
|
SessionSecret: []byte("0123456789abcdef0123456789abcdef"),
|
|
}
|
|
entries := map[string]string{}
|
|
for _, e := range cfg.DisplayEnv() {
|
|
entries[e.Name] = e.Value
|
|
}
|
|
if entries["GENIUSRUN_BACKEND_ADDR"] != ":8080" {
|
|
t.Errorf("GENIUSRUN_BACKEND_ADDR = %q", entries["GENIUSRUN_BACKEND_ADDR"])
|
|
}
|
|
if entries["GENIUSRUN_OIDC_CLIENT_SECRET"] != "•••• (set)" {
|
|
t.Errorf("client secret not masked: %q", entries["GENIUSRUN_OIDC_CLIENT_SECRET"])
|
|
}
|
|
if entries["GENIUSRUN_SESSION_SECRET"] != "•••• (set)" {
|
|
t.Errorf("session secret not masked: %q", entries["GENIUSRUN_SESSION_SECRET"])
|
|
}
|
|
empty := EnvConfig{}
|
|
for _, e := range empty.DisplayEnv() {
|
|
if e.Name == "GENIUSRUN_OIDC_CLIENT_SECRET" && e.Value != "(unset)" {
|
|
t.Errorf("unset secret = %q, want (unset)", e.Value)
|
|
}
|
|
}
|
|
}
|