using Halo.Core.Library;
namespace Halo.Core.Tests;
public class LibraryWalkerTests
{
private string _wurzel = "";
[SetUp]
public void Anlegen() => _wurzel = Directory.CreateDirectory(
Path.Combine(Path.GetTempPath(), "halo-bestand-" + Guid.CreateVersion7().ToString("N"))).FullName;
[TearDown]
public void Aufraeumen()
{
foreach (var d in Directory.EnumerateDirectories(_wurzel, "*", SearchOption.AllDirectories))
File.SetUnixFileMode(d, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
try { Directory.Delete(_wurzel, recursive: true); } catch (IOException) { }
}
private void Datei(string relativ, int bytes = 1024)
{
var voll = Path.Combine(_wurzel, relativ);
Directory.CreateDirectory(Path.GetDirectoryName(voll)!);
File.WriteAllBytes(voll, new byte[bytes]);
}
private string[] GefundeneNamen(WalkResult ergebnis) =>
ergebnis.Files.Select(f => Path.GetFileName(f.Path)).Order().ToArray();
[Test]
public void Videodateien_werden_gefunden_Beiwerk_nicht()
{
Datei("Filme/The Matrix (1999).mkv");
Datei("Filme/The Matrix (1999).srt");
Datei("Filme/poster.jpg");
Datei("Filme/The Matrix (1999).nfo");
Assert.That(GefundeneNamen(LibraryWalker.Walk(_wurzel)), Is.EqualTo(new[] { "The Matrix (1999).mkv" }));
}
[Test]
public void Auch_tief_verschachtelt_wird_gefunden()
{
Datei("Serien/Dark/Staffel 1/Dark - S01E01.mkv");
Datei("Serien/Dark/Staffel 2/Dark - S02E01.mkv");
Assert.That(LibraryWalker.Walk(_wurzel).Files, Has.Count.EqualTo(2));
}
/// Der Fund, der eine Mediathek sonst verdoppelt.
///
///
/// @eaDir ist Synologys Vorschauablage und enthält eine Kopie jeder
/// Datei. Mit SearchOption.AllDirectories — der bequemen
/// Fassung — liefe der Scan hinein und fände jeden Film zweimal, einmal
/// davon als unbrauchbare Kopie. Genau deshalb steigt der Walker von Hand
/// ab.
///
[Test]
public void Vorschauablagen_und_Papierkoerbe_werden_uebersprungen()
{
Datei("Filme/The Matrix (1999).mkv");
Datei("Filme/@eaDir/The Matrix (1999).mkv/SYNOPHOTO_THUMB.mkv");
Datei("Filme/#recycle/Alter Film (2001).mkv");
Datei("Filme/.versteckt/Noch einer (2002).mkv");
Datei("Filme/Extras/Making Of.mkv");
Assert.That(GefundeneNamen(LibraryWalker.Walk(_wurzel)), Is.EqualTo(new[] { "The Matrix (1999).mkv" }));
}
[Test]
public void Groesse_und_Aenderungszeit_kommen_mit()
{
Datei("Filme/Film (2000).mkv", bytes: 4096);
var gefunden = LibraryWalker.Walk(_wurzel).Files.Single();
Assert.That(gefunden.SizeBytes, Is.EqualTo(4096));
Assert.That(gefunden.ModifiedAt, Is.GreaterThan(DateTimeOffset.UtcNow.AddMinutes(-5)));
}
/// Ein gesperrter Ordner darf nicht den ganzen Lauf verderben.
///
///
/// Sonst entschiede ein einzelner falsch gesetzter Unterordner darüber, ob
/// überhaupt etwas gefunden wird — und die Mediathek bliebe leer, ohne dass
/// jemand sagen könnte, warum.
///
[Test]
public void Ein_gesperrter_Ordner_wird_vermerkt_und_uebersprungen()
{
if (OperatingSystem.IsWindows()) Assert.Ignore("Dateirechte verhalten sich dort anders.");
Datei("Filme/Erreichbar (2000).mkv");
var gesperrt = Directory.CreateDirectory(Path.Combine(_wurzel, "Filme", "gesperrt")).FullName;
File.WriteAllBytes(Path.Combine(gesperrt, "Versteckt (2001).mkv"), new byte[10]);
File.SetUnixFileMode(gesperrt, UnixFileMode.None);
var ergebnis = LibraryWalker.Walk(_wurzel);
Assert.That(GefundeneNamen(ergebnis), Is.EqualTo(new[] { "Erreichbar (2000).mkv" }));
Assert.That(ergebnis.Problems, Has.Count.EqualTo(1));
Assert.That(ergebnis.Problems[0].Path, Is.EqualTo(gesperrt));
}
[Test]
public void Ein_Verzeichnis_das_es_nicht_gibt_wird_gemeldet_statt_zu_werfen()
{
var ergebnis = LibraryWalker.Walk(Path.Combine(_wurzel, "gibtesnicht"));
Assert.That(ergebnis.Files, Is.Empty);
Assert.That(ergebnis.Problems, Has.Count.EqualTo(1));
}
[Test]
public void Ein_leerer_Bestand_ist_kein_Fehler()
{
var ergebnis = LibraryWalker.Walk(_wurzel);
Assert.That(ergebnis.Files, Is.Empty);
Assert.That(ergebnis.Problems, Is.Empty);
}
}
public class SortTitleTests
{
[TestCase("Der Untergang", "Untergang")]
[TestCase("Die Welle", "Welle")]
[TestCase("Das Boot", "Boot")]
[TestCase("The Matrix", "Matrix")]
[TestCase("A Quiet Place", "Quiet Place")]
[TestCase("An American Werewolf", "American Werewolf")]
[TestCase("Blade Runner", "Blade Runner")]
[TestCase("Theater", "Theater")]
public void Der_Artikel_faellt_fuers_Sortieren_weg(string titel, string erwartet)
{
Assert.That(SortTitle.For(titel), Is.EqualTo(erwartet));
}
/// Ein Titel, der nur aus einem Artikel besteht, bleibt stehen.
[TestCase("Die")]
[TestCase("The")]
public void Ein_blosser_Artikel_bleibt_als_Titel_erhalten(string titel)
{
Assert.That(SortTitle.For(titel), Is.EqualTo(titel));
}
}