package service import ( "testing" "vidarchive/internal/models" ) func TestPresetServiceBuildArgs(t *testing.T) { // Create a mock preset preset := &models.Preset{ FormatMode: "preset", Format: "best", Quality: "1080", ExtractAudio: true, AudioFormat: "mp3", EmbedSubs: true, SubLangs: "en,de", EmbedThumbnail: true, EmbedMetadata: true, WriteInfoJSON: true, CustomFlags: "--no-playlist", } svc := &PresetService{} args := svc.BuildArgs(preset, "", "") // Check that expected args are present hasFormat := false hasAudio := false hasSubs := false hasOutput := false for i := 0; i < len(args); i++ { switch args[i] { case "-f": if i+1 < len(args) { if args[i+1] == "best[height<=1080]/best" { hasFormat = true } } case "--extract-audio": hasAudio = true case "--embed-subs": hasSubs = true case "-o": if i+1 < len(args) { if args[i+1] == "item-%(autonumber)05d/%(title)s.%(ext)s" { hasOutput = true } } } } if !hasFormat { t.Error("expected format arg with quality limit") } if !hasAudio { t.Error("expected --extract-audio flag") } if !hasSubs { t.Error("expected --embed-subs flag") } if hasOutput { t.Error("output template should not be added by BuildArgs; it is enforced by the download service") } } func TestPresetServiceBuildArgsWithOverride(t *testing.T) { preset := &models.Preset{ Format: "best", } svc := &PresetService{} args := svc.BuildArgs(preset, "22", "--verbose") // Format override should take precedence hasOverride := false hasCustom := false for i := 0; i < len(args); i++ { if args[i] == "-f" && i+1 < len(args) && args[i+1] == "22" { hasOverride = true } if args[i] == "--verbose" { hasCustom = true } } if !hasOverride { t.Error("expected format override to be present") } if !hasCustom { t.Error("expected custom flags to be present") } } func TestPresetServiceBuildArgsWithComments(t *testing.T) { preset := &models.Preset{ WriteComments: true, CommentSort: "top", MaxComments: 25, CommentExtractorArgs: "youtube:player_client=web", } args := (&PresetService{}).BuildArgs(preset, "", "") want := []string{"--write-info-json", "--write-comments", "--extractor-args", "youtube:comment_sort=top,max_comments=25", "--extractor-args", "youtube:player_client=web"} for _, value := range want { found := false for _, arg := range args { if arg == value { found = true break } } if !found { t.Errorf("BuildArgs missing %q: %v", value, args) } } } func TestPresetServiceIgnoresWhitespaceCommentSort(t *testing.T) { preset := &models.Preset{WriteComments: true, CommentSort: " "} flags := (&PresetService{}).EffectiveFlags(preset, "", "") if contains(flags, "comment_sort=") { t.Fatalf("whitespace-only comment sort emitted an empty argument: %q", flags) } } func TestPresetServiceEffectiveFlags(t *testing.T) { preset := &models.Preset{ FormatMode: "preset", Format: "best", Quality: "720", } svc := &PresetService{} flags := svc.EffectiveFlags(preset, "", "") if flags == "" { t.Error("expected non-empty flags string") } if flags != "-f best[height<=720]/best" { t.Errorf("expected '-f best[height<=720]/best', got %q", flags) } } func TestPresetServiceEffectiveFlagsWithCustom(t *testing.T) { preset := &models.Preset{ FormatMode: "preset", Format: "best", CustomFlags: "--no-warnings", } svc := &PresetService{} flags := svc.EffectiveFlags(preset, "", "--verbose") if flags == "" { t.Error("expected non-empty flags string") } // Should contain both preset custom flags and passed custom flags if !contains(flags, "--no-warnings") { t.Errorf("expected flags to contain '--no-warnings', got %q", flags) } if !contains(flags, "--verbose") { t.Errorf("expected flags to contain '--verbose', got %q", flags) } } func contains(s, substr string) bool { return len(s) >= len(substr) && (s == substr || len(s) > 0 && containsHelper(s, substr)) } func containsHelper(s, substr string) bool { for i := 0; i <= len(s)-len(substr); i++ { if s[i:i+len(substr)] == substr { return true } } return false }