using Flaro.Core.Library; namespace Flaro.Core.Tests; /// Was Flaro in einen Medienordner schreiben darf. /// /// /// Die wichtigste Prüfdatei des Projekts. Damit Plakate neben dem Film /// landen können, ist die Einhängung schreibbar — und damit hängt der Schutz /// des gesamten Bestands an dieser einen Liste. /// public class SidecarNamesTests { [TestCase("poster.jpg")] [TestCase("fanart.jpg")] [TestCase("logo.png")] [TestCase("movie.nfo")] [TestCase("tvshow.nfo")] [TestCase("Dark - S01E01.nfo")] [TestCase("Dark - S01E01-thumb.jpg")] [TestCase("POSTER.JPG")] public void Beiwerk_darf_geschrieben_werden(string name) { Assert.That(SidecarNames.MayWrite(name), Is.True); } /// Eine Mediendatei wird nie angefasst — auch nicht, wenn jemand es verlangt. [TestCase("film.mkv")] [TestCase("Der Untergang (2004).mp4")] [TestCase("film.mkv.nfo.mkv")] public void Mediendateien_niemals(string name) { Assert.That(SidecarNames.MayWrite(name), Is.False); } /// Kein Weg aus dem Ordner heraus. /// /// /// Käme hier ein Pfadbestandteil durch, liesse sich über einen /// erfundenen „Dateinamen" in jedes Verzeichnis des Containers /// schreiben — auch in das, in dem die Datenbank liegt. /// [TestCase("../poster.jpg")] [TestCase("../../etc/passwd")] [TestCase("/etc/poster.jpg")] [TestCase("unterordner/poster.jpg")] [TestCase("..\\poster.jpg")] [TestCase("ordner\\movie.nfo")] [TestCase("..movie.nfo")] public void Kein_Pfad_kommt_durch(string versuch) { Assert.That(SidecarNames.MayWrite(versuch), Is.False); } [TestCase("")] [TestCase(" ")] [TestCase(".nfo")] [TestCase("-thumb.jpg")] [TestCase(".versteckt.nfo")] [TestCase("poster.png")] [TestCase("beliebig.txt")] public void Alles_andere_wird_abgelehnt(string versuch) { Assert.That(SidecarNames.MayWrite(versuch), Is.False); } /// Zwei Filme im selben Ordner dürfen sich nicht überschreiben. [Test] public void Beiwerk_mit_Dateinamen_davor_ist_auch_erlaubt() { Assert.That(SidecarNames.Prefixed("Matrix (1999).mkv", SidecarNames.MoviePoster), Is.EqualTo("Matrix (1999)-poster.jpg")); foreach (var beiwerk in new[] { SidecarNames.MoviePoster, SidecarNames.MovieBackdrop, SidecarNames.MovieLogo }) Assert.That(SidecarNames.MayWrite(SidecarNames.Prefixed("Matrix (1999).mkv", beiwerk)), Is.True); } [Test] public void Folgen_Beiwerk_heisst_wie_die_Folge() { Assert.That(SidecarNames.EpisodeNfo("Dark - S01E01.mkv"), Is.EqualTo("Dark - S01E01.nfo")); Assert.That(SidecarNames.EpisodeThumb("Dark - S01E01.mkv"), Is.EqualTo("Dark - S01E01-thumb.jpg")); } /// Was erzeugt wird, muss auch erlaubt sein. /// /// /// Die beiden Hälften könnten auseinanderlaufen — jemand ändert das Muster /// für Folgen und vergisst die Liste. Dann schriebe Flaro nichts mehr und /// niemand wüsste, warum. /// [TestCase("Dark - S01E01.mkv")] [TestCase("Notruf.Hafenkante.S01E01.German.1080p.mkv")] [TestCase("Serie 1x01.avi")] public void Die_erzeugten_Namen_stehen_auf_der_Liste(string mediendatei) { Assert.That(SidecarNames.MayWrite(SidecarNames.EpisodeNfo(mediendatei)), Is.True); Assert.That(SidecarNames.MayWrite(SidecarNames.EpisodeThumb(mediendatei)), Is.True); } } public class ProviderIdParserTests { [Test] public void Eine_TMDB_Kennung_im_Ordnernamen_wird_gelesen() { var kennungen = ProviderIdParser.FromPath("/media/Filme/Der Untergang (2004) [tmdbid-613]/film.mkv"); Assert.That(kennungen.Tmdb, Is.EqualTo(613)); } [Test] public void Eine_IMDb_Kennung_wird_gelesen_und_kleingeschrieben() { var kennungen = ProviderIdParser.FromPath("/media/Filme/Matrix (1999) [imdbid-TT0133093]/film.mkv"); Assert.That(kennungen.Imdb, Is.EqualTo("tt0133093")); } [Test] public void Beide_nebeneinander_gehen_auch() { var kennungen = ProviderIdParser.FromPath("/m/Film (2004) [tmdbid-613] [imdbid-tt0363163]/f.mkv"); Assert.That((kennungen.Tmdb, kennungen.Imdb), Is.EqualTo((613, "tt0363163"))); } [TestCase("/media/Filme/Der Untergang (2004)/film.mkv")] [TestCase("/media/Filme/Film [1080p]/film.mkv")] [TestCase("")] [TestCase("/media/Film [tmdbid-]/f.mkv")] [TestCase("/media/Film [imdbid-nichts]/f.mkv")] public void Ohne_Kennung_kommt_nichts_zurueck(string pfad) { Assert.That(ProviderIdParser.FromPath(pfad).Any, Is.False); } } public class NfoTests { [Test] public void Ein_Film_wird_geschrieben_und_wieder_gelesen() { var xml = Nfo.Write(new MovieNfo( "Der Untergang", 2004, "Berlin, April 1945.", new ProviderIds(613, "tt0363163"), Locked: true)); Assert.That(xml, Does.StartWith("Der Untergang")); Assert.That(xml, Does.Contain("2004")); var gelesen = Nfo.ReadIds(xml); Assert.That((gelesen.Tmdb, gelesen.Imdb), Is.EqualTo((613, "tt0363163"))); Assert.That(Nfo.ReadLocked(xml), Is.True); } /// Kennungen stehen doppelt drin, für alte wie neue Werkzeuge. [Test] public void Die_Kennungen_stehen_in_beiden_Formen_da() { var xml = Nfo.Write(new MovieNfo("Egal", null, null, new ProviderIds(613, "tt0363163"), false)); Assert.That(xml, Does.Contain("""613""")); Assert.That(xml, Does.Contain("613")); Assert.That(xml, Does.Contain("""tt0363163""")); Assert.That(xml, Does.Contain("tt0363163")); } [Test] public void Die_aeltere_Form_allein_wird_auch_gelesen() { var gelesen = Nfo.ReadIds("613tt0363163"); Assert.That((gelesen.Tmdb, gelesen.Imdb), Is.EqualTo((613, "tt0363163"))); } [Test] public void Sonderzeichen_im_Titel_werden_richtig_geschrieben() { var xml = Nfo.Write(new MovieNfo("Tom & Jerry ", null, null, ProviderIds.None, false)); Assert.That(xml, Does.Contain("Tom & Jerry <der Film>")); Assert.That(Nfo.ReadIds(xml).Any, Is.False, "Und die Datei bleibt lesbar"); } /// Eine von Hand geschriebene NFO ist oft kaputt — das darf nichts abbrechen. [TestCase("")] [TestCase("kein xml")] [TestCase("offen")] [TestCase("<movie><tmdbid>keine zahl</tmdbid></movie>")] public void Unlesbares_ergibt_nichts_statt_eines_Absturzes(string kaputt) { Assert.That(Nfo.ReadIds(kaputt).Any, Is.False); Assert.That(Nfo.ReadLocked(kaputt), Is.False); } /// <summary>Eine NFO aus dem Medienordner hat Flaro nicht geschrieben.</summary> /// /// <remarks> /// <b>Ohne abgeschaltete DTDs wäre das ein Weg, fremde Dateien zu lesen.</b> /// Eine untergeschobene NFO mit einer externen Entität könnte den Server /// dazu bringen, <c>/config/flaro.db</c> einzulesen und den Inhalt als /// Titel auszuliefern. /// </remarks> [Test] public void Eine_NFO_mit_externer_Entitaet_wird_nicht_ausgewertet() { var angriff = """ <?xml version="1.0"?> <!DOCTYPE movie [<!ENTITY xxe SYSTEM "file:///etc/passwd">]> <movie><title>&xxe;613 """; Assert.That(Nfo.ReadIds(angriff).Any, Is.False, "Die Datei wird gar nicht erst verarbeitet"); Assert.That(Nfo.ReadLocked(angriff), Is.False); } [Test] public void Eine_Folge_bekommt_Staffel_und_Nummer() { var xml = Nfo.Write(new EpisodeNfo("Geheimnisse", 1, 1, "Ein Junge verschwindet.")); Assert.That(xml, Does.Contain("1")); Assert.That(xml, Does.Contain("1")); Assert.That(xml, Does.Contain("Geheimnisse")); } }