using System.Text; using Flaro.Core.Library; using Microsoft.Extensions.Logging.Abstractions; namespace Flaro.Media.Tests; /// Was wirklich auf der Platte landet. public class SidecarWriterTests { private string _ordner = ""; private string _film = ""; [SetUp] public void Anlegen() { _ordner = Directory.CreateDirectory(Path.Combine( Path.GetTempPath(), "flaro-beiwerk-" + Guid.CreateVersion7().ToString("N"), "Der Untergang (2004)")).FullName; _film = Path.Combine(_ordner, "Der Untergang (2004).mkv"); File.WriteAllBytes(_film, new byte[2048]); } [TearDown] public void Aufraeumen() { try { Directory.Delete(Path.GetDirectoryName(_ordner)!, recursive: true); } catch (IOException) { } } private static SidecarWriter Schreiber(bool an = true) => new(new SidecarOptions(an), NullLogger.Instance); [Test] public async Task Eine_NFO_landet_neben_dem_Film() { await Schreiber().WriteTextAsync(_film, SidecarNames.MovieNfo, "613"); var ziel = Path.Combine(_ordner, "movie.nfo"); Assert.That(File.Exists(ziel), Is.True); Assert.That(await File.ReadAllTextAsync(ziel), Does.Contain("613")); } [Test] public async Task Ein_Bild_landet_neben_dem_Film() { using var inhalt = new MemoryStream(Encoding.UTF8.GetBytes("ein plakat")); await Schreiber().WriteStreamAsync(_film, SidecarNames.MoviePoster, inhalt); Assert.That(File.Exists(Path.Combine(_ordner, "poster.jpg")), Is.True); } /// Die Prüfung, an der der Schutz des Bestands hängt. /// /// /// Es muss laut scheitern, nicht still übergehen. Käme hier ein /// Name durch, der nicht auf der Liste steht, wäre der gesamte Bestand /// offen — und ein stilles Übergehen verstecke den Fehler, bis jemand /// seine Filme vermisst. /// [TestCase("film.mkv")] [TestCase("../anderswo.nfo")] [TestCase("/etc/passwd")] [TestCase("unterordner/poster.jpg")] [TestCase("beliebig.txt")] public void Was_nicht_auf_der_Liste_steht_wird_laut_abgelehnt(string versuch) { var fehler = Assert.ThrowsAsync( () => Schreiber().WriteTextAsync(_film, versuch, "egal")); Assert.That(fehler!.Message, Does.Contain("Liste")); } /// Die Mediendatei bleibt unberührt — auch beim Versuch. [Test] public void Die_Mediendatei_wird_nie_angefasst() { var vorher = new FileInfo(_film).Length; Assert.ThrowsAsync( () => Schreiber().WriteTextAsync(_film, "Der Untergang (2004).mkv", "kaputt")); Assert.That(new FileInfo(_film).Length, Is.EqualTo(vorher)); Assert.That(File.ReadAllBytes(_film).All(b => b == 0), Is.True); } /// Abgeschaltet heisst abgeschaltet. [Test] public async Task Ohne_Erlaubnis_wird_nichts_geschrieben() { await Schreiber(an: false).WriteTextAsync(_film, SidecarNames.MovieNfo, ""); Assert.That(File.Exists(Path.Combine(_ordner, "movie.nfo")), Is.False); Assert.That(Schreiber(an: false).Enabled, Is.False); } /// Gelesen wird trotzdem. /// /// /// Eine vorhandene NFO ist eine Zuordnung, die jemand getroffen hat. Sie /// zu übergehen, bloss weil Flaro selbst nicht schreiben darf, wäre /// verkehrt herum. /// [Test] public async Task Gelesen_wird_auch_ohne_Schreiberlaubnis() { await File.WriteAllTextAsync(Path.Combine(_ordner, "movie.nfo"), "613"); var gelesen = await Schreiber(an: false).ReadTextAsync(_film, SidecarNames.MovieNfo); Assert.That(Nfo.ReadIds(gelesen!).Tmdb, Is.EqualTo(613)); } [Test] public async Task Eine_fehlende_Datei_ergibt_null() { Assert.That(await Schreiber().ReadTextAsync(_film, SidecarNames.MovieNfo), Is.Null); } [Test] public async Task Ein_zweites_Schreiben_ersetzt_das_erste() { await Schreiber().WriteTextAsync(_film, SidecarNames.MovieNfo, "alt"); await Schreiber().WriteTextAsync(_film, SidecarNames.MovieNfo, "neu"); Assert.That(await File.ReadAllTextAsync(Path.Combine(_ordner, "movie.nfo")), Is.EqualTo("neu")); Assert.That(Directory.GetFiles(_ordner, "*.flaro-tmp"), Is.Empty, "Keine Reste vom Umbenennen"); } [Test] public void Ein_Film_allein_im_Ordner_wird_erkannt() { Assert.That(Schreiber().IsAloneInFolder(_film), Is.True); File.WriteAllBytes(Path.Combine(_ordner, "Noch ein Film (2005).mkv"), new byte[10]); Assert.That(Schreiber().IsAloneInFolder(_film), Is.False); } /// Beiwerk zählt nicht als zweiter Film. [Test] public async Task Das_eigene_Beiwerk_macht_den_Film_nicht_unselbstaendig() { await Schreiber().WriteTextAsync(_film, SidecarNames.MovieNfo, ""); using var bild = new MemoryStream([1, 2, 3]); await Schreiber().WriteStreamAsync(_film, SidecarNames.MoviePoster, bild); Assert.That(Schreiber().IsAloneInFolder(_film), Is.True); } }