package cmd import ( "bytes" "io" "os" "testing" ) // TestLoginCommand tests the login CLI command func TestLoginCommand(t *testing.T) { t.Parallel() // Create a temporary config file tmpDir := t.TempDir() configPath := tmpDir + "/config.yaml" configContent := ` api: base_url: "http://localhost:8080" timeout: 30s ` err := os.WriteFile(configPath, []byte(configContent), 0644) if err != nil { t.Fatalf("Failed to write config: %v", err) } // Set config path environment variable os.Setenv("POP_CONFIG_PATH", configPath) defer os.Unsetenv("POP_CONFIG_PATH") // Create root command with login subcommand rootCmd := NewRootCmd() rootCmd.SetArgs([]string{"login"}) // Capture output var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) // Execute command err = rootCmd.Execute() if err != nil { // Login requires interactive input, so error is expected in non-interactive mode t.Logf("Login command executed with error (expected in non-interactive mode): %v", err) } // Verify command ran output := buf.String() t.Logf("Command output: %s", output) } // TestLogoutCommand tests the logout CLI command func TestLogoutCommand(t *testing.T) { t.Parallel() // Create a temporary config file tmpDir := t.TempDir() configPath := tmpDir + "/config.yaml" err := os.WriteFile(configPath, []byte("{}"), 0644) if err != nil { t.Fatalf("Failed to write config: %v", err) } os.Setenv("POP_CONFIG_PATH", configPath) defer os.Unsetenv("POP_CONFIG_PATH") // Create root command with logout subcommand rootCmd := NewRootCmd() rootCmd.SetArgs([]string{"logout"}) // Capture output var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) // Execute command err = rootCmd.Execute() // Logout may fail if no session exists, which is expected if err != nil { t.Logf("Logout command executed with error (expected if no session): %v", err) } } // TestSessionCommand tests the session CLI command func TestSessionCommand(t *testing.T) { t.Parallel() // Create a temporary config file tmpDir := t.TempDir() configPath := tmpDir + "/config.yaml" err := os.WriteFile(configPath, []byte("{}"), 0644) if err != nil { t.Fatalf("Failed to write config: %v", err) } os.Setenv("POP_CONFIG_PATH", configPath) defer os.Unsetenv("POP_CONFIG_PATH") // Create root command with session subcommand rootCmd := NewRootCmd() rootCmd.SetArgs([]string{"session"}) // Capture output var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) // Execute command err = rootCmd.Execute() // Session may fail if no active session, which is expected if err != nil { t.Logf("Session command executed with error (expected if no session): %v", err) } } // TestRootCommandHelp tests the help output func TestRootCommandHelp(t *testing.T) { t.Parallel() rootCmd := NewRootCmd() rootCmd.SetArgs([]string{"--help"}) var buf bytes.Buffer rootCmd.SetOut(&buf) err := rootCmd.Execute() if err != nil { t.Fatalf("Help command failed: %v", err) } output, _ := io.ReadAll(&buf) if len(output) == 0 { t.Error("Help output is empty") } // Verify help contains expected commands helpText := string(output) expectedCommands := []string{"login", "logout", "session", "mail", "contact", "attachment", "folder", "draft"} for _, cmd := range expectedCommands { if !contains(helpText, cmd) { t.Errorf("Help output missing command: %s", cmd) } } } // Helper function to check if string contains substring func contains(s, substr string) bool { return len(s) > 0 && len(substr) > 0 && (s == substr || len(s) > len(substr) && (s[:len(substr)] == substr || contains(s[1:], substr))) }