package organize import ( "os" "path/filepath" "testing" "git.meatbag.se/varl/subsyt/internal/config" "git.meatbag.se/varl/subsyt/internal/fsops" "git.meatbag.se/varl/subsyt/internal/metadata" ) func TestOrganizerProcess(t *testing.T) { root := t.TempDir() paths := config.Paths{ DownloadRoot: filepath.Join(root, "downloads"), ChannelsDir: filepath.Join(root, "downloads", "channels"), EpisodesDir: filepath.Join(root, "downloads", "episodes"), MediaDir: filepath.Join(root, "library"), } if err := os.MkdirAll(paths.ChannelsDir, 0o755); err != nil { t.Fatalf("mkdir channels: %v", err) } if err := os.MkdirAll(paths.EpisodesDir, 0o755); err != nil { t.Fatalf("mkdir episodes: %v", err) } showSub := filepath.Join(paths.ChannelsDir, "sNA") if err := os.MkdirAll(showSub, 0o755); err != nil { t.Fatalf("mkdir show subdir: %v", err) } showBase := filepath.Join(showSub, "test-channel") showInfo := showBase + ".info.json" showImage := showBase + ".jpg" showJSON := `{"channel":"Test Channel","channel_id":"chan123","description":"Show description","thumbnails":[]}` if err := os.WriteFile(showInfo, []byte(showJSON), 0o644); err != nil { t.Fatalf("write show info: %v", err) } if err := os.WriteFile(showImage, []byte("poster"), 0o644); err != nil { t.Fatalf("write show image: %v", err) } seasonDir := filepath.Join(paths.EpisodesDir, "s2024") if err := os.MkdirAll(seasonDir, 0o755); err != nil { t.Fatalf("mkdir season: %v", err) } base := filepath.Join(seasonDir, "Test Channel.s2024Se0210S.Sample.abc123") infoPath := base + ".info.json" videoPath := base + ".mp4" subsPath := base + ".en.vtt" thumbPath := base + ".jpg" epJSON := `{"title":"Episode","channel":"Test Channel","id":"abc123","description":"Episode description","upload_date":"20240210","ext":"mp4"}` if err := os.WriteFile(infoPath, []byte(epJSON), 0o644); err != nil { t.Fatalf("write episode info: %v", err) } if err := os.WriteFile(videoPath, []byte("video"), 0o644); err != nil { t.Fatalf("write episode video: %v", err) } if err := os.WriteFile(subsPath, []byte("subtitles"), 0o644); err != nil { t.Fatalf("write subtitles: %v", err) } if err := os.WriteFile(thumbPath, []byte("thumb"), 0o644); err != nil { t.Fatalf("write thumb: %v", err) } shows, err := metadata.ScanShows(paths.ChannelsDir) if err != nil { t.Fatalf("scan shows: %v", err) } episodes, err := metadata.ScanEpisodes(paths.EpisodesDir) if err != nil { t.Fatalf("scan episodes: %v", err) } organizer := Organizer{ Paths: paths, FS: fsops.Manager{DryRun: false}, } if err := organizer.Prepare(); err != nil { t.Fatalf("prepare: %v", err) } if err := organizer.ProcessShows(shows); err != nil { t.Fatalf("process shows: %v", err) } if err := organizer.ProcessEpisodes(episodes); err != nil { t.Fatalf("process episodes: %v", err) } showDir := filepath.Join(paths.MediaDir, "Test Channel") seasonOut := filepath.Join(showDir, "s2024") if _, err := os.Stat(filepath.Join(showDir, "tvshow.nfo")); err != nil { t.Fatalf("expected tvshow.nfo: %v", err) } if _, err := os.Stat(filepath.Join(showDir, "poster.jpg")); err != nil { t.Fatalf("expected poster.jpg: %v", err) } if _, err := os.Stat(filepath.Join(seasonOut, filepath.Base(videoPath))); err != nil { t.Fatalf("expected moved video: %v", err) } if _, err := os.Stat(filepath.Join(seasonOut, "Test Channel.s2024Se0210S.Sample.abc123-thumb.jpg")); err != nil { t.Fatalf("expected moved thumbnail: %v", err) } if _, err := os.Stat(filepath.Join(seasonOut, "Test Channel.s2024Se0210S.Sample.abc123.en.vtt")); err != nil { t.Fatalf("expected moved subtitles: %v", err) } if _, err := os.Stat(filepath.Join(seasonOut, "Test Channel.s2024Se0210S.Sample.abc123.nfo")); err != nil { t.Fatalf("expected episode nfo: %v", err) } if _, err := os.Stat(infoPath); !os.IsNotExist(err) { t.Fatalf("expected episode info removed, got err=%v", err) } if _, err := os.Stat(showInfo); !os.IsNotExist(err) { t.Fatalf("expected show info removed, got err=%v", err) } }