package main import ( "os" "path/filepath" "testing" "github.com/stretchr/testify/require" ) func TestLoadConfigGivesDefaultsWithoutAFile(t *testing.T) { dir := t.TempDir() config, err := loadConfig(dir) require.NoError(t, err) require.Equal(t, defaultConfig(), config) require.NoFileExists(t, filepath.Join(dir, "config.json")) } func TestLoadConfigKeepsDefaultsForMissingFields(t *testing.T) { dir := t.TempDir() writeConfig(t, dir, `{"endpoint": "api", "compactor": {"effort": "xhigh"}}`) config, err := loadConfig(dir) require.NoError(t, err) require.Equal(t, Config{ Endpoint: endpointAPI, Compactor: ModelConfig{ Model: "gpt-6-luna", Effort: "xhigh", }, }, config) } func TestLoadConfigRejectsInvalidFiles(t *testing.T) { testCases := []struct { name string text string }{ { name: "unknown field", text: `{"endpont": "api"}`, }, { name: "unknown nested field", text: `{"compactor": {"modle": "x"}}`, }, { name: "endpoint URL", text: `{"endpoint": "https://example.com/v1/responses"}`, }, { name: "empty model", text: `{"compactor": {"model": ""}}`, }, { name: "second object", text: `{} {}`, }, { name: "broken JSON", text: `{"endpoint": `, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { dir := t.TempDir() writeConfig(t, dir, tc.text) _, err := loadConfig(dir) require.Error(t, err) }) } } func TestDataDirFollowsTheOrder(t *testing.T) { root := t.TempDir() testCases := []struct { name string dir string xdg string home string want string }{ { name: "ONECHAT_DIR first", dir: filepath.Join(root, "a"), xdg: filepath.Join(root, "xdg"), home: root, want: filepath.Join(root, "a"), }, { name: "absolute XDG_DATA_HOME", dir: "", xdg: filepath.Join(root, "xdg"), home: root, want: filepath.Join(root, "xdg", "onechat"), }, { name: "relative XDG_DATA_HOME ignored", dir: "", xdg: "xdg", home: root, want: filepath.Join(root, ".local", "share", "onechat"), }, { name: "home directory last", dir: "", xdg: "", home: root, want: filepath.Join(root, ".local", "share", "onechat"), }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Setenv("ONECHAT_DIR", tc.dir) t.Setenv("XDG_DATA_HOME", tc.xdg) t.Setenv("HOME", tc.home) dir, err := dataDir() require.NoError(t, err) require.Equal(t, tc.want, dir) info, err := os.Stat(dir) require.NoError(t, err) require.Equal(t, os.FileMode(0o700), info.Mode().Perm()) }) } } func TestDataDirFailsWithoutAHome(t *testing.T) { t.Setenv("ONECHAT_DIR", "") t.Setenv("XDG_DATA_HOME", "") t.Setenv("HOME", "") _, err := dataDir() require.ErrorContains(t, err, "ONECHAT_DIR") } func writeConfig(t *testing.T, dir, text string) { t.Helper() err := os.WriteFile(filepath.Join(dir, "config.json"), []byte(text), 0o600) require.NoError(t, err) }