diff --git a/Packages/FlixyKit/Sources/JellyfinKit/JellyfinBackend.swift b/Packages/FlixyKit/Sources/JellyfinKit/JellyfinBackend.swift index 546cc46..b840ac1 100644 --- a/Packages/FlixyKit/Sources/JellyfinKit/JellyfinBackend.swift +++ b/Packages/FlixyKit/Sources/JellyfinKit/JellyfinBackend.swift @@ -73,14 +73,7 @@ public func isInLocalNetwork() async -> Bool { as: JellyfinItemPage.self ) return page.items.map { view in - let kind: MediaLibrary.Kind = switch view.collectionType { - case "movies": .movie - case "tvshows": .show - case "music": .music - case "homevideos", "photos": .photo - case "livetv": .liveTV - default: .other - } + let kind = MediaLibrary.Kind(jellyfinCollectionType: view.collectionType) return MediaLibrary( id: view.id, title: view.name ?? "—", @@ -634,3 +627,31 @@ extension MediaQuery.Sort { } } } + +extension MediaLibrary.Kind { + /// Was Jellyfin als Art einer Mediathek meldet. + /// + /// **Eigene Funktion, damit sie prüfbar ist.** Die Zuordnung entscheidet + /// mehr, als sie aussieht: was hier als `.photo` oder `.music` landet, + /// fällt unter `MediaLibrary.isSupported` heraus und ist in der App + /// **gar nicht vorhanden** — keine Reihe, kein Eintrag in der Leiste, + /// nicht einmal in der Auswahl für den Aufmacher. Ein Fehler hier sieht + /// aus wie eine Mediathek, die der Server nicht liefert. + /// + /// Genau das war mit `homevideos` der Fall: Jellyfin nennt „Heimvideos & + /// Fotos" so, und weil Fotos im Namen stehen, lag es bei den Fotos. Der + /// Inhalt sind Videos. + init(jellyfinCollectionType: String?) { + switch jellyfinCollectionType { + case "movies": self = .movie + case "tvshows": self = .show + case "music": self = .music + case "photos": self = .photo + case "livetv": self = .liveTV + // Auch `homevideos`, `musicvideos`, `mixed` und alles Unbekannte: + // Videos, die man ansehen kann, auch wenn der Server sie nicht + // einsortiert. + default: self = .other + } + } +} diff --git a/Packages/FlixyKit/Tests/JellyfinKitTests/TranslationTests.swift b/Packages/FlixyKit/Tests/JellyfinKitTests/TranslationTests.swift index 07097fd..ab713ae 100644 --- a/Packages/FlixyKit/Tests/JellyfinKitTests/TranslationTests.swift +++ b/Packages/FlixyKit/Tests/JellyfinKitTests/TranslationTests.swift @@ -182,3 +182,42 @@ struct TranslationTests { return item.asMediaItem(imageBase: JellyfinImagePaths()) } } + +@Suite("Die Art einer Mediathek") +struct LibraryKindTests { + + @Test( + "Die bekannten Arten", + arguments: [ + ("movies", MediaLibrary.Kind.movie), + ("tvshows", .show), + ("music", .music), + ("photos", .photo), + ("livetv", .liveTV), + ] + ) + func mapsKnownTypes(type: String, expected: MediaLibrary.Kind) { + #expect(MediaLibrary.Kind(jellyfinCollectionType: type) == expected) + } + + /// **Der Fall, der eine ganze Mediathek verschwinden liess.** Jellyfin + /// nennt „Heimvideos & Fotos" `homevideos`; weil Fotos im Namen stehen, + /// lag es bei den Fotos — und fiel damit unter `isSupported` heraus. Die + /// Mediathek war in der App nicht vorhanden, nicht einmal in der Auswahl + /// für den Aufmacher. + @Test("Heimvideos sind Videos, keine Fotos") + func homeVideosAreWatchable() { + let art = MediaLibrary.Kind(jellyfinCollectionType: "homevideos") + #expect(art == .other) + #expect(MediaLibrary(id: "1", title: "Videos", kind: art).isSupported) + } + + /// Eine gemischte Mediathek meldet gar keine Art. Sie deshalb + /// wegzulassen hiesse, den häufigsten selbstgebauten Fall zu übersehen. + @Test("Ohne Angabe bleibt sie trotzdem da") + func unknownStays() { + let art = MediaLibrary.Kind(jellyfinCollectionType: nil) + #expect(art == .other) + #expect(MediaLibrary(id: "1", title: "Gemischtes", kind: art).isSupported) + } +}