package appview import ( "os" "testing" "time" ) func Test_getServiceName(t *testing.T) { tests := []struct { name string baseURL string envService string setEnv bool want string }{ { name: "env var set", baseURL: "http://127.0.0.1:5000", envService: "custom.registry.io", setEnv: true, want: "custom.registry.io", }, { name: "localhost - use default", baseURL: "http://localhost:5000", setEnv: false, want: "atcr.io", }, { name: "127.0.0.1 - use default", baseURL: "http://127.0.0.1:5000", setEnv: false, want: "atcr.io", }, { name: "custom domain", baseURL: "https://registry.example.com", setEnv: false, want: "registry.example.com", }, { name: "domain with port", baseURL: "https://registry.example.com:443", setEnv: false, want: "registry.example.com", }, { name: "invalid URL - use default", baseURL: "://invalid", setEnv: false, want: "atcr.io", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.setEnv { t.Setenv("ATCR_SERVICE_NAME", tt.envService) } else { os.Unsetenv("ATCR_SERVICE_NAME") } got := getServiceName(tt.baseURL) if got != tt.want { t.Errorf("getServiceName() = %v, want %v", got, tt.want) } }) } } // TestBuildLogConfig removed - buildLogConfig is now an internal function // TestBuildHTTPConfig removed - buildHTTPConfig is now an internal function func TestBuildStorageConfig(t *testing.T) { got := buildStorageConfig() // Verify inmemory driver exists if _, ok := got["inmemory"]; !ok { t.Error("buildStorageConfig() missing inmemory driver") } // Verify maintenance config maintenance, ok := got["maintenance"] if !ok { t.Fatal("buildStorageConfig() missing maintenance config") } uploadPurging, ok := maintenance["uploadpurging"] if !ok { t.Fatal("buildStorageConfig() missing uploadpurging config") } // Verify uploadpurging is map[any]any (for distribution validation) purging, ok := uploadPurging.(map[any]any) if !ok { t.Fatalf("uploadpurging is %T, want map[any]any", uploadPurging) } if purging["enabled"] != false { t.Error("uploadpurging enabled should be false") } } func TestBuildMiddlewareConfig(t *testing.T) { tests := []struct { name string defaultHoldDID string baseURL string testMode bool setTestMode bool wantTestMode bool }{ { name: "normal mode", defaultHoldDID: "did:web:hold01.atcr.io", baseURL: "https://atcr.io", setTestMode: false, wantTestMode: false, }, { name: "test mode enabled", defaultHoldDID: "did:web:hold01.atcr.io", baseURL: "https://atcr.io", testMode: true, setTestMode: true, wantTestMode: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.setTestMode { t.Setenv("TEST_MODE", "true") } else { os.Unsetenv("TEST_MODE") } got := buildMiddlewareConfig(tt.defaultHoldDID, tt.baseURL) registryMW, ok := got["registry"] if !ok { t.Fatal("buildMiddlewareConfig() missing registry middleware") } if len(registryMW) != 1 { t.Fatalf("buildMiddlewareConfig() registry middleware count = %v, want 1", len(registryMW)) } mw := registryMW[0] if mw.Name != "atproto-resolver" { t.Errorf("middleware name = %v, want atproto-resolver", mw.Name) } if mw.Options["default_hold_did"] != tt.defaultHoldDID { t.Errorf("default_hold_did = %v, want %v", mw.Options["default_hold_did"], tt.defaultHoldDID) } if mw.Options["base_url"] != tt.baseURL { t.Errorf("base_url = %v, want %v", mw.Options["base_url"], tt.baseURL) } if mw.Options["test_mode"] != tt.wantTestMode { t.Errorf("test_mode = %v, want %v", mw.Options["test_mode"], tt.wantTestMode) } }) } } func TestBuildHealthConfig(t *testing.T) { got := buildHealthConfig() if !got.StorageDriver.Enabled { t.Error("buildHealthConfig().StorageDriver.Enabled = false, want true") } if got.StorageDriver.Interval.Seconds() != 10 { t.Errorf("buildHealthConfig().StorageDriver.Interval = %v, want 10s", got.StorageDriver.Interval) } if got.StorageDriver.Threshold != 3 { t.Errorf("buildHealthConfig().StorageDriver.Threshold = %v, want 3", got.StorageDriver.Threshold) } } func TestLoadConfigFromEnv(t *testing.T) { tests := []struct { name string envHoldDID string setHoldDID bool wantError bool }{ { name: "valid config", envHoldDID: "did:web:hold01.atcr.io", setHoldDID: true, wantError: false, }, { name: "missing default hold DID", setHoldDID: false, wantError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.setHoldDID { t.Setenv("ATCR_DEFAULT_HOLD_DID", tt.envHoldDID) } else { os.Unsetenv("ATCR_DEFAULT_HOLD_DID") } // Clear other env vars to use defaults os.Unsetenv("ATCR_BASE_URL") os.Unsetenv("ATCR_SERVICE_NAME") got, err := LoadConfigFromEnv() if (err != nil) != tt.wantError { t.Errorf("LoadConfigFromEnv() error = %v, wantError %v", err, tt.wantError) return } if tt.wantError { return } // Verify config structure if got.Version != "0.1" { t.Errorf("version = %v, want 0.1", got.Version) } if got.LogLevel != "info" { t.Errorf("log level = %v, want info", got.LogLevel) } if got.Server.Addr != ":5000" { t.Errorf("HTTP addr = %v, want :5000", got.Server.Addr) } if got.Server.DefaultHoldDID != tt.envHoldDID { t.Errorf("default hold DID = %v, want %v", got.Server.DefaultHoldDID, tt.envHoldDID) } if got.UI.DatabasePath != "/var/lib/atcr/ui.db" { t.Errorf("UI database path = %v, want /var/lib/atcr/ui.db", got.UI.DatabasePath) } if got.Health.CacheTTL != 15*time.Minute { t.Errorf("health cache TTL = %v, want 15m", got.Health.CacheTTL) } if got.Jetstream.URL != "wss://jetstream2.us-west.bsky.network/subscribe" { t.Errorf("jetstream URL = %v, want default", got.Jetstream.URL) } // Verify distribution config was built if got.Distribution == nil { t.Error("distribution config is nil") } if _, ok := got.Distribution.Storage["inmemory"]; !ok { t.Error("distribution storage missing inmemory driver") } if _, ok := got.Distribution.Middleware["registry"]; !ok { t.Error("distribution middleware missing registry") } if _, ok := got.Distribution.Auth["token"]; !ok { t.Error("distribution auth missing token config") } }) } }