import Foundation import Testing import MediaKit @testable import PlexKit /// Die Übersetzung der Plex-Modelle in die neutrale Form. /// /// Gegen eine echte Server-Antwort, nicht gegen erfundene Werte: die /// Eigenheiten, an denen eine Übersetzung scheitert, stehen genau dort — /// „grandparent" für die Serie, Sekunden seit 1970 als Zahl, Fassungen und /// Dateien ineinander verschachtelt. @Suite("Übersetzung nach MediaKit") struct MediaTranslationTests { private func item(_ fixture: String) throws -> PlexItem { let url = try #require(Bundle.module.url(forResource: "Fixtures/\(fixture)", withExtension: "json")) let container = try PlexResponse.decode( PlexMediaContainer.self, from: try Data(contentsOf: url) ) return try #require(container.content.first) } @Test("Aus dem Großelternteil wird die Serie") func translatesTheGrandparent() throws { let episode = try item("episodes-unanalyzed").asMediaItem // Der Name war von Anfang an irreführend: gemeint ist die Serie, und // in jeder Ansicht musste man ihn im Kopf übersetzen. #expect(episode.kind == .episode) #expect(episode.title == "Die erste Folge") #expect(episode.seriesTitle == "Eine Serie") #expect(episode.index == 1) #expect(episode.parentIndex == 1) } @Test("Fassungen und Dateien kommen vollständig mit") func translatesVersions() throws { let movie = try item("movie-with-two-versions").asMediaItem #expect(movie.versions.count == 2) #expect(movie.hasMultipleVersions) let first = try #require(movie.versions.first) #expect(first.files.isEmpty == false) #expect(first.container != nil) } @Test("Die Wiedergabe-Entscheidung bekommt dasselbe Profil wie vorher") func buildsTheSameProfile() throws { // Beide Wege müssen dasselbe sagen — sonst spielte ein Titel nach dem // Umbau plötzlich über einen anderen Player. let plex = try item("movie-with-two-versions") let media = try #require(plex.media.first) let part = try #require(media.parts.first) let viaPlex = media.profile(part: part) let viaMedia = try #require(plex.asMediaItem.versions.first) .profile(file: plex.asMediaItem.versions.first?.files.first) #expect(viaPlex == viaMedia) } @Test("Ohne Fortschritt gibt es keinen Balken") func leavesUnstartedItemsAlone() throws { let movie = try item("movie-with-two-versions").asMediaItem // `watchProgress` ist bewusst `nil` statt 0: ein Balken bei null // Prozent sieht aus wie ein Fehler, nicht wie „noch nicht begonnen". if movie.resumeMilliseconds == nil || movie.resumeMilliseconds == 0 { #expect(movie.watchProgress == nil) } } @Test("Plex kennt keine Favoriten und behauptet auch keine") func doesNotInventFavourites() throws { #expect(try item("movie-with-two-versions").asMediaItem.isFavourite == false) } }