package main import ( "bytes" "context" "os" "path/filepath" "runtime" "strings" "testing" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/ungluedlabs/go-jdenticon/jdenticon" ) // TestGenerateCommand tests the generate command functionality func TestGenerateCommand(t *testing.T) { tests := []struct { name string args []string wantErr bool outputCheck func(t *testing.T, output []byte, outputFile string) }{ { name: "generate SVG to stdout", args: []string{"generate", "test@example.com"}, wantErr: false, outputCheck: func(t *testing.T, output []byte, outputFile string) { if !bytes.Contains(output, []byte("", Short: "Generate a single identicon", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { // Get the input value value := args[0] // Get output file flag outputFile, _ := cmd.Flags().GetString("output") // Get format from viper format, err := getFormatFromViper() if err != nil { return err } // Populate library config from root persistent flags config, size, err := populateConfigFromFlags() if err != nil { return err } // Generate the identicon with custom config generator, err := jdenticon.NewGeneratorWithConfig(config, generatorCacheSize) if err != nil { return err } icon, err := generator.Generate(context.Background(), value, size) if err != nil { return err } // Generate output based on format result, err := renderIcon(icon, format) if err != nil { return err } // Output to file or stdout if outputFile != "" { // Determine the base directory for allowed writes. For a CLI, this is typically the CWD. baseDir, err := os.Getwd() if err != nil { return err } // Validate and resolve the user-provided output path. safeOutputPath, err := validateAndResolveOutputPath(baseDir, outputFile) if err != nil { // This is a security-related error, explicitly state it. return err } // Now use the safe and validated path for writing. if err := os.WriteFile(safeOutputPath, result, 0644); err != nil { return err } } else { // Write to stdout for piping if _, err := cmd.OutOrStdout().Write(result); err != nil { return err } } return nil }, } // Add generate-specific flags generateCmd.Flags().StringP("output", "o", "", "Output file path. If empty, writes to stdout.") // Add to root command rootCmd.AddCommand(generateCmd) return rootCmd }