import XCTest @testable import TVAnarchyCore final class WatchStateTests: XCTestCase { private func show() -> CachedShow { let eps = [ CachedEpisode(path: "/p/D/s1e1.mkv", season: 1, episode: 1, label: "S1E1"), CachedEpisode(path: "/p/D/s1e2.mkv", season: 1, episode: 2, label: "S1E2"), CachedEpisode(path: "/p/D/s2e1.mkv", season: 2, episode: 1, label: "S2E1"), CachedEpisode(path: "/p/D/movie.mkv", season: 0, episode: 1, label: "Movie"), ] return CachedShow(name: "Daria", rootDir: "/r/D", category: "cartoons", kind: .series, episodes: eps) } /// resumePositions keys are black-side paths; these test paths aren't under a /// known mount, so toRemote leaves them unchanged. private func watched(_ paths: [String]) -> Set { Set(paths) } func testWatchStateTransitions() { let d = show() XCTAssertEqual(d.watchState(watchedPaths: []), .unwatched) XCTAssertEqual(d.watchState(watchedPaths: watched(["/p/D/s1e1.mkv"])), .inProgress) XCTAssertEqual(d.watchState(watchedPaths: watched(["/p/D/s1e1.mkv", "/p/D/s1e2.mkv", "/p/D/s2e1.mkv", "/p/D/movie.mkv"])), .watched) } func testNextUnwatchedSkipsStartedEpisodesInPlayOrder() { let d = show() // started S1E1, S1E2 → next is S2E1 (before the season-0 movie). XCTAssertEqual(d.nextUnwatched(watchedPaths: watched(["/p/D/s1e1.mkv", "/p/D/s1e2.mkv"]))?.path, "/p/D/s2e1.mkv") // nothing watched → first episode. XCTAssertEqual(d.nextUnwatched(watchedPaths: [])?.path, "/p/D/s1e1.mkv") // all watched → nil (caller offers rewatch). XCTAssertNil(d.nextUnwatched(watchedPaths: watched(["/p/D/s1e1.mkv", "/p/D/s1e2.mkv", "/p/D/s2e1.mkv", "/p/D/movie.mkv"]))) } func testIsWatchedEpisode() { let d = show() XCTAssertTrue(d.isWatched(d.episodes[0], watchedPaths: watched(["/p/D/s1e1.mkv"]))) XCTAssertFalse(d.isWatched(d.episodes[1], watchedPaths: watched(["/p/D/s1e1.mkv"]))) } }