package main import ( "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/vaughan0/go-ini" "sourcecraft.dev/bigbes/sr-ht-ecore/instconf" ) // loadConf builds an ini.File directly from a literal, bypassing // config.LoadConfig so the tests need no config.ini on disk and no // internal-ipnet parsing. func loadConf(t *testing.T, body string) ini.File { t.Helper() conf, err := ini.Load(strings.NewReader(body)) if err != nil { t.Fatalf("ini.Load: %v", err) } return conf } func TestResolveSettingsDefaults(t *testing.T) { conf := loadConf(t, `[dolt.sr.ht] origin=https://dolt.example.org connection-string=postgres://u@localhost/d?sslmode=disable `) got, err := resolveSettings(conf) if err != nil { t.Fatalf("resolveSettings: %v", err) } if got.connString != "postgres://u@localhost/d?sslmode=disable" { t.Errorf("connString = %q", got.connString) } if got.httpHost != "dolt.example.org" { t.Errorf("httpHost = %q, want dolt.example.org", got.httpHost) } if got.reposRoot != defaultReposRoot { t.Errorf("reposRoot = %q, want %q", got.reposRoot, defaultReposRoot) } if got.staticDir != defaultStaticDir { t.Errorf("staticDir = %q, want %q", got.staticDir, defaultStaticDir) } if got.remotesapiAddr != defaultRemotesapiAddr { t.Errorf("remotesapiAddr = %q, want %q", got.remotesapiAddr, defaultRemotesapiAddr) } if got.credsapiAddr != defaultCredsapiAddr { t.Errorf("credsapiAddr = %q, want %q", got.credsapiAddr, defaultCredsapiAddr) } } func TestResolveSettingsOverrides(t *testing.T) { conf := loadConf(t, `[dolt.sr.ht] origin=https://dolt.example.org:8443 connection-string=postgres://u@localhost/d repos=/srv/dolt static-dir=/usr/share/sourcehut/dolt.sr.ht/static remotesapi-listen=0.0.0.0:6306 credsapi-listen=0.0.0.0:6308 `) got, err := resolveSettings(conf) if err != nil { t.Fatalf("resolveSettings: %v", err) } if got.reposRoot != "/srv/dolt" { t.Errorf("reposRoot = %q", got.reposRoot) } if got.staticDir != "/usr/share/sourcehut/dolt.sr.ht/static" { t.Errorf("staticDir = %q", got.staticDir) } if got.remotesapiAddr != "0.0.0.0:6306" { t.Errorf("remotesapiAddr = %q", got.remotesapiAddr) } if got.credsapiAddr != "0.0.0.0:6308" { t.Errorf("credsapiAddr = %q", got.credsapiAddr) } // The port is part of the sealed-URL authority and is preserved. if got.httpHost != "dolt.example.org:8443" { t.Errorf("httpHost = %q, want dolt.example.org:8443", got.httpHost) } } func TestResolveSettingsMissingConnString(t *testing.T) { conf := loadConf(t, `[dolt.sr.ht] origin=https://dolt.example.org `) _, err := resolveSettings(conf) require.Error(t, err) assert.ErrorIs(t, err, instconf.ErrIncompleteConfig) assert.Contains(t, err.Error(), "connection-string") } func TestResolveSettingsMissingOrigin(t *testing.T) { conf := loadConf(t, `[dolt.sr.ht] connection-string=postgres://u@localhost/d `) _, err := resolveSettings(conf) require.Error(t, err) assert.ErrorIs(t, err, instconf.ErrIncompleteConfig) assert.Contains(t, err.Error(), "origin") } // TestResolveSettingsReportsEveryMissingKey is the reason the two checks became // one Require: an operator with an empty section gets both keys off one boot // rather than one key per restart. func TestResolveSettingsReportsEveryMissingKey(t *testing.T) { _, err := resolveSettings(loadConf(t, "[dolt.sr.ht]\n")) require.Error(t, err) assert.Contains(t, err.Error(), "connection-string") assert.Contains(t, err.Error(), "origin") } // TestResolveSettingsHostlessOrigin covers the gap Require cannot: a present, // non-blank origin that names no host. "dolt.example.org" without a scheme is a // URL path, and a service whose sealed chunk URLs and JWT audience are built // from an empty authority must refuse to start rather than guess a host. func TestResolveSettingsHostlessOrigin(t *testing.T) { conf := loadConf(t, `[dolt.sr.ht] connection-string=postgres://u@localhost/d origin=dolt.example.org `) _, err := resolveSettings(conf) require.Error(t, err) assert.Contains(t, err.Error(), "names no host") } // TestResolveSettingsTrimsTheOrigin: an origin written with a trailing slash is // the same origin. It used to reach url.Parse untouched, which happened to // answer the same host; the authority now comes off the canonical form, so the // two spellings cannot diverge for any other consumer either. func TestResolveSettingsTrimsTheOrigin(t *testing.T) { conf := loadConf(t, `[dolt.sr.ht] connection-string=postgres://u@localhost/d origin=https://dolt.example.org:8443/ `) got, err := resolveSettings(conf) require.NoError(t, err) assert.Equal(t, "dolt.example.org:8443", got.httpHost) }