package config import ( "os" "path/filepath" "testing" "time" ) func TestLoadConfigNotExists(t *testing.T) { // Override config path to use temp file originalHome := os.Getenv("HOME") tempDir := t.TempDir() os.Setenv("HOME", tempDir) defer os.Setenv("HOME", originalHome) cfg, err := Load() if err != nil { t.Fatalf("expected no error when config doesn't exist, got: %v", err) } if cfg.Version != ConfigVersion { t.Errorf("expected version %s, got %s", ConfigVersion, cfg.Version) } if len(cfg.Repos) != 0 { t.Errorf("expected empty repos, got %d repos", len(cfg.Repos)) } } func TestLoadConfigExists(t *testing.T) { originalHome := os.Getenv("HOME") tempDir := t.TempDir() os.Setenv("HOME", tempDir) defer os.Setenv("HOME", originalHome) // Create a config file configPath := filepath.Join(tempDir, ConfigFile) configContent := `version: "1" repos: - path: /test/path/1 converted_at: 2026-04-07T14:30:00Z original_remote: git@github.com:user/repo1.git original_branch: main - path: /test/path/2 converted_at: 2026-04-07T15:00:00Z original_remote: git@github.com:user/repo2.git original_branch: develop ` if err := os.WriteFile(configPath, []byte(configContent), 0644); err != nil { t.Fatalf("failed to write test config: %v", err) } cfg, err := Load() if err != nil { t.Fatalf("failed to load config: %v", err) } if cfg.Version != "1" { t.Errorf("expected version 1, got %s", cfg.Version) } if len(cfg.Repos) != 2 { t.Fatalf("expected 2 repos, got %d", len(cfg.Repos)) } if cfg.Repos[0].Path != "/test/path/1" { t.Errorf("expected path /test/path/1, got %s", cfg.Repos[0].Path) } if cfg.Repos[0].OriginalRemote != "git@github.com:user/repo1.git" { t.Errorf("expected remote git@github.com:user/repo1.git, got %s", cfg.Repos[0].OriginalRemote) } } func TestSaveConfig(t *testing.T) { originalHome := os.Getenv("HOME") tempDir := t.TempDir() os.Setenv("HOME", tempDir) defer os.Setenv("HOME", originalHome) cfg := &Config{ Version: ConfigVersion, Repos: []Repo{ { Path: "/test/repo", ConvertedAt: time.Now(), OriginalRemote: "git@github.com:test/repo.git", OriginalBranch: "main", }, }, } if err := cfg.Save(); err != nil { t.Fatalf("failed to save config: %v", err) } configPath := filepath.Join(tempDir, ConfigFile) if _, err := os.Stat(configPath); os.IsNotExist(err) { t.Fatalf("config file was not created") } // Load it back to verify loadedCfg, err := Load() if err != nil { t.Fatalf("failed to load saved config: %v", err) } if len(loadedCfg.Repos) != 1 { t.Fatalf("expected 1 repo, got %d", len(loadedCfg.Repos)) } if loadedCfg.Repos[0].Path != "/test/repo" { t.Errorf("expected path /test/repo, got %s", loadedCfg.Repos[0].Path) } } func TestAddRepo(t *testing.T) { cfg := &Config{ Version: ConfigVersion, Repos: []Repo{}, } repo1 := Repo{ Path: "/test/repo1", ConvertedAt: time.Now(), OriginalRemote: "git@github.com:test/repo1.git", OriginalBranch: "main", } cfg.AddRepo(repo1) if len(cfg.Repos) != 1 { t.Fatalf("expected 1 repo, got %d", len(cfg.Repos)) } if cfg.Repos[0].Path != "/test/repo1" { t.Errorf("expected path /test/repo1, got %s", cfg.Repos[0].Path) } } func TestAddRepoReplaceExisting(t *testing.T) { now := time.Now() later := now.Add(1 * time.Hour) cfg := &Config{ Version: ConfigVersion, Repos: []Repo{ { Path: "/test/repo", ConvertedAt: now, OriginalRemote: "git@github.com:test/old.git", OriginalBranch: "main", }, }, } // Add same path again with different data repo := Repo{ Path: "/test/repo", ConvertedAt: later, OriginalRemote: "git@github.com:test/new.git", OriginalBranch: "develop", } cfg.AddRepo(repo) if len(cfg.Repos) != 1 { t.Fatalf("expected 1 repo (replaced), got %d", len(cfg.Repos)) } if cfg.Repos[0].OriginalRemote != "git@github.com:test/new.git" { t.Errorf("expected new remote, got %s", cfg.Repos[0].OriginalRemote) } if cfg.Repos[0].OriginalBranch != "develop" { t.Errorf("expected branch develop, got %s", cfg.Repos[0].OriginalBranch) } if !cfg.Repos[0].ConvertedAt.Equal(later) { t.Errorf("expected later timestamp") } } func TestRemoveRepo(t *testing.T) { cfg := &Config{ Version: ConfigVersion, Repos: []Repo{ {Path: "/test/repo1"}, {Path: "/test/repo2"}, {Path: "/test/repo3"}, }, } cfg.RemoveRepo("/test/repo2") if len(cfg.Repos) != 2 { t.Fatalf("expected 2 repos, got %d", len(cfg.Repos)) } for _, repo := range cfg.Repos { if repo.Path == "/test/repo2" { t.Errorf("repo2 should have been removed") } } } func TestRemoveRepoNotFound(t *testing.T) { cfg := &Config{ Version: ConfigVersion, Repos: []Repo{ {Path: "/test/repo1"}, }, } cfg.RemoveRepo("/test/nonexistent") if len(cfg.Repos) != 1 { t.Fatalf("expected 1 repo, got %d", len(cfg.Repos)) } } func TestFindRepo(t *testing.T) { cfg := &Config{ Version: ConfigVersion, Repos: []Repo{ { Path: "/test/repo1", OriginalRemote: "git@github.com:test/repo1.git", }, { Path: "/test/repo2", OriginalRemote: "git@github.com:test/repo2.git", }, }, } repo := cfg.FindRepo("/test/repo1") if repo == nil { t.Fatalf("expected to find repo1") } if repo.OriginalRemote != "git@github.com:test/repo1.git" { t.Errorf("expected repo1 remote, got %s", repo.OriginalRemote) } } func TestFindRepoNotFound(t *testing.T) { cfg := &Config{ Version: ConfigVersion, Repos: []Repo{ {Path: "/test/repo1"}, }, } repo := cfg.FindRepo("/test/nonexistent") if repo != nil { t.Errorf("expected nil for nonexistent repo, got %v", repo) } }