package cmd import ( "bytes" "os" "path/filepath" "strings" "testing" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/iwasforcedtobehere/git-automation-cli/internal/config" ) func TestConfigGetCmd(t *testing.T) { // Save original config and viper originalConfig := config.GlobalConfig originalViper := viper.GetViper() defer func() { config.GlobalConfig = originalConfig config.SetViper(originalViper) }() // Create a new viper instance for testing testViper := viper.New() config.SetViper(testViper) // Create a temporary config file tempDir := t.TempDir() configFile := filepath.Join(tempDir, "config.yaml") // Set config file path in viper testViper.SetConfigFile(configFile) testViper.SetConfigType("yaml") // Create the config file if err := os.WriteFile(configFile, []byte("default_remote: origin\ndefault_branch: main\ngithub_url: https://api.github.com\ngithub_token: ghp_testtoken123456\nauto_cleanup: true\nconfirm_destructive: true\ndry_run: false\nverbose: false\nbranch_prefix: feature/\nfeature_prefix: feature/\nhotfix_prefix: hotfix/\n"), 0644); err != nil { t.Fatalf("Failed to create config file: %v", err) } // Read the config file if err := testViper.ReadInConfig(); err != nil { t.Fatalf("Failed to read config file: %v", err) } // Set up test config config.GlobalConfig = &config.Config{ DefaultRemote: "origin", DefaultBranch: "main", GitHubURL: "https://api.github.com", GitHubToken: "ghp_testtoken123456", AutoCleanup: true, ConfirmDestructive: true, DryRun: false, Verbose: false, BranchPrefix: "feature/", FeaturePrefix: "feature/", HotfixPrefix: "hotfix/", } // Set values in viper testViper.Set("default_remote", "origin") testViper.Set("default_branch", "main") testViper.Set("github_url", "https://api.github.com") testViper.Set("github_token", "ghp_testtoken123456") testViper.Set("auto_cleanup", true) testViper.Set("confirm_destructive", true) testViper.Set("dry_run", false) testViper.Set("verbose", false) testViper.Set("branch_prefix", "feature/") testViper.Set("feature_prefix", "feature/") testViper.Set("hotfix_prefix", "hotfix/") // Set the config file path config.SetConfigFile(configFile) tests := []struct { name string args []string wantOutput string wantError bool }{ { name: "Get all config", args: []string{}, wantOutput: "Configuration file: " + configFile + "\n\nDefault Remote: origin\nDefault Branch: main\nGitHub URL: https://api.github.com\nAuto Cleanup: true\nConfirm Destructive: true\nDry Run: false\nVerbose: false\nBranch Prefix: feature/\nFeature Prefix: feature/\nHotfix Prefix: hotfix/\nGitHub Token: ghp_****************************3456\n", wantError: false, }, { name: "Get specific config", args: []string{"default_remote"}, wantOutput: "default_remote: origin\n", wantError: false, }, { name: "Get sensitive config", args: []string{"github_token"}, wantOutput: "github_token: ghp_****************************3456\n", wantError: false, }, { name: "Get non-existent config", args: []string{"nonexistent"}, wantOutput: "", // Don't check exact output for error case wantError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Use the actual configGetCmd cmd := &cobra.Command{ Use: "get", Args: cobra.MaximumNArgs(1), RunE: configGetCmd.RunE, SilenceUsage: true, // Prevent usage output on errors } // Capture output output := &bytes.Buffer{} cmd.SetOut(output) cmd.SetErr(output) // Set args cmd.SetArgs(tt.args) // Execute command err := cmd.Execute() // Check error expectation if tt.wantError && err == nil { t.Errorf("Execute() error = %v, wantError %v", err, tt.wantError) return } if !tt.wantError && err != nil { t.Errorf("Execute() error = %v, wantError %v", err, tt.wantError) return } // Check output for error cases if tt.wantError { outputStr := output.String() if !strings.Contains(outputStr, "Configuration key 'nonexistent' not found") { t.Errorf("Expected error output to contain 'Configuration key 'nonexistent' not found', got %q", outputStr) } return } // Check output for success cases if output.String() != tt.wantOutput { t.Errorf("Execute() output = %q, want %q", output.String(), tt.wantOutput) } }) } } func TestConfigSetCmd(t *testing.T) { // Save original config and viper originalConfig := config.GlobalConfig originalViper := viper.GetViper() defer func() { config.GlobalConfig = originalConfig config.SetViper(originalViper) }() // Create a new viper instance for testing testViper := viper.New() config.SetViper(testViper) // Create a temporary config file tempDir := t.TempDir() configFile := filepath.Join(tempDir, "config.yaml") // Set config file path in viper testViper.SetConfigFile(configFile) testViper.SetConfigType("yaml") // Create the config file if err := os.WriteFile(configFile, []byte("default_remote: origin\ndefault_branch: main\n"), 0644); err != nil { t.Fatalf("Failed to create config file: %v", err) } // Read the config file if err := testViper.ReadInConfig(); err != nil { t.Fatalf("Failed to read config file: %v", err) } // Set up test config config.GlobalConfig = &config.Config{ DefaultRemote: "origin", DefaultBranch: "main", } // Set values in viper testViper.Set("default_remote", "origin") testViper.Set("default_branch", "main") // Set the config file path config.SetConfigFile(configFile) // Create a command cmd := &cobra.Command{ Use: "set", Args: cobra.ExactArgs(2), RunE: configSetCmd.RunE, } // Capture output output := &bytes.Buffer{} cmd.SetOut(output) cmd.SetErr(output) // Set args cmd.SetArgs([]string{"default_branch", "develop"}) // Execute command err := cmd.Execute() // Check error if err != nil { t.Errorf("Execute() error = %v", err) return } // Check output expected := "Set default_branch = develop\n" if output.String() != expected { t.Errorf("Execute() output = %q, want %q", output.String(), expected) } // Check that config was updated if config.GlobalConfig.DefaultBranch != "develop" { t.Errorf("Expected DefaultBranch to be 'develop', got '%s'", config.GlobalConfig.DefaultBranch) } } func TestConfigInitCmd(t *testing.T) { // Save original config and viper originalConfig := config.GlobalConfig originalViper := viper.GetViper() defer func() { config.GlobalConfig = originalConfig config.SetViper(originalViper) }() // Create a new viper instance for testing testViper := viper.New() config.SetViper(testViper) // Create a temporary config file tempDir := t.TempDir() configFile := filepath.Join(tempDir, "config.yaml") // Set config file path in viper testViper.SetConfigFile(configFile) testViper.SetConfigType("yaml") // Create a command // Set the config file path to our temp file before creating the command config.SetConfigFile(configFile) cmd := &cobra.Command{ Use: "init", RunE: configInitCmd.RunE, } // Capture output output := &bytes.Buffer{} cmd.SetOut(output) cmd.SetErr(output) // Execute command err := cmd.Execute() // Check error if err != nil { t.Errorf("Execute() error = %v", err) return } // Check output contains expected text outputStr := output.String() if !strings.Contains(outputStr, "Configuration file created at:") { t.Errorf("Expected output to contain 'Configuration file created at:', got %q", outputStr) } }