diff --git a/cmd/download.go b/cmd/download.go index c4c668f..b88cc62 100644 --- a/cmd/download.go +++ b/cmd/download.go @@ -28,8 +28,6 @@ func newDownloadCmd() *cobra.Command { cmd.PersistentFlags().BoolVar(&opts.Genre, "genre", false, "fetch genre and add to file tags") cmd.PersistentFlags().BoolVar(&opts.Strict, "strict", false, "fail the download if the requested quality is unavailable") - // Every subcommand shares opts: registering the artist-only --limit flag - // stores its default in the shared struct, which Validate requires for all kinds. cmd.AddCommand( newDownloadSubCmd(deezer.KindAlbum, opts), newDownloadSubCmd(deezer.KindPlaylist, opts), @@ -47,7 +45,7 @@ func newDownloadSubCmd(kind deezer.Kind, opts *download.Options) *cobra.Command Args: cobra.ExactArgs(1), PreRunE: func(cmd *cobra.Command, args []string) error { opts.Quality = strings.ToLower(opts.Quality) - return opts.Validate() + return opts.Validate(kind) }, RunE: func(cmd *cobra.Command, args []string) error { cfg, err := config.Load() diff --git a/internal/download/options.go b/internal/download/options.go index 2f0c9a7..1355354 100644 --- a/internal/download/options.go +++ b/internal/download/options.go @@ -3,6 +3,8 @@ package download import ( "fmt" "time" + + "github.com/mathismqn/godeez/internal/deezer" ) var validQualities = map[string]bool{ @@ -20,18 +22,20 @@ type Options struct { Strict bool } -func (o *Options) Validate() error { +func (o *Options) Validate(kind deezer.Kind) error { if !validQualities[o.Quality] { return fmt.Errorf("invalid quality option: %s", o.Quality) } if o.Timeout <= 0 { return fmt.Errorf("timeout must be a positive duration") } - if o.Limit <= 0 { - return fmt.Errorf("limit must be a positive integer") - } - if o.Limit > 100 { - return fmt.Errorf("limit must not exceed 100") + if kind == deezer.KindArtist { + if o.Limit <= 0 { + return fmt.Errorf("limit must be a positive integer") + } + if o.Limit > 100 { + return fmt.Errorf("limit must not exceed 100") + } } return nil diff --git a/internal/download/options_test.go b/internal/download/options_test.go index a2aa1b2..791a262 100644 --- a/internal/download/options_test.go +++ b/internal/download/options_test.go @@ -3,6 +3,8 @@ package download import ( "testing" "time" + + "github.com/mathismqn/godeez/internal/deezer" ) func TestOptionsValidate(t *testing.T) { @@ -11,18 +13,21 @@ func TestOptionsValidate(t *testing.T) { tests := []struct { name string mutate func(o *Options) + kind deezer.Kind wantErr bool }{ - {"valid", func(o *Options) {}, false}, - {"mp3_128", func(o *Options) { o.Quality = "mp3_128" }, false}, - {"flac", func(o *Options) { o.Quality = "flac" }, false}, - {"invalid quality", func(o *Options) { o.Quality = "ogg" }, true}, - {"uppercase quality", func(o *Options) { o.Quality = "MP3_320" }, true}, - {"zero timeout", func(o *Options) { o.Timeout = 0 }, true}, - {"negative timeout", func(o *Options) { o.Timeout = -time.Second }, true}, - {"zero limit", func(o *Options) { o.Limit = 0 }, true}, - {"limit too high", func(o *Options) { o.Limit = 101 }, true}, - {"limit at max", func(o *Options) { o.Limit = 100 }, false}, + {"valid", func(o *Options) {}, deezer.KindAlbum, false}, + {"mp3_128", func(o *Options) { o.Quality = "mp3_128" }, deezer.KindAlbum, false}, + {"flac", func(o *Options) { o.Quality = "flac" }, deezer.KindAlbum, false}, + {"invalid quality", func(o *Options) { o.Quality = "ogg" }, deezer.KindAlbum, true}, + {"uppercase quality", func(o *Options) { o.Quality = "MP3_320" }, deezer.KindAlbum, true}, + {"zero timeout", func(o *Options) { o.Timeout = 0 }, deezer.KindAlbum, true}, + {"negative timeout", func(o *Options) { o.Timeout = -time.Second }, deezer.KindAlbum, true}, + {"artist zero limit", func(o *Options) { o.Limit = 0 }, deezer.KindArtist, true}, + {"artist limit too high", func(o *Options) { o.Limit = 101 }, deezer.KindArtist, true}, + {"artist limit at max", func(o *Options) { o.Limit = 100 }, deezer.KindArtist, false}, + {"album ignores zero limit", func(o *Options) { o.Limit = 0 }, deezer.KindAlbum, false}, + {"track ignores zero limit", func(o *Options) { o.Limit = 0 }, deezer.KindTrack, false}, } for _, tt := range tests { @@ -30,9 +35,9 @@ func TestOptionsValidate(t *testing.T) { opts := valid tt.mutate(&opts) - err := opts.Validate() + err := opts.Validate(tt.kind) if (err != nil) != tt.wantErr { - t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("Validate(%s) error = %v, wantErr %v", tt.kind, err, tt.wantErr) } }) }