using AvParser.Infrastructure.Storage; namespace AvParser.Infrastructure.Tests; public sealed class AppPathsTests : IDisposable { private readonly string _root = Path.Combine(Path.GetTempPath(), "AvParserTests", Guid.NewGuid().ToString("N")); public void Dispose() { if (Directory.Exists(_root)) { Directory.Delete(_root, recursive: true); } } [Fact] public void Media_defaults_to_a_folder_beside_the_application() { // The collection is the point of the app and grows without bound, so it belongs where the // app was put: copy that folder and the archive travels with it. var media = AppPaths.DefaultMediaDirectory(); Path.GetFileName(media).ShouldBe("media"); Path.GetDirectoryName(media).ShouldBe(Path.TrimEndingDirectorySeparator(AppContext.BaseDirectory)); } [Fact] public void Settings_and_logs_stay_in_the_profile() { // Only media moves next to the executable. Configuration is per-user and belongs where the // operating system says it does. var paths = new AppPaths(); paths.SettingsFile.ShouldStartWith(AppPaths.ProfileDirectory()); paths.LogDirectory.ShouldStartWith(AppPaths.ProfileDirectory()); paths.MediaDirectory.ShouldNotStartWith(AppPaths.ProfileDirectory()); } [Fact] public void An_explicit_media_root_wins() { var elsewhere = Path.Combine(_root, "archive"); var paths = new AppPaths(_root, elsewhere); paths.MediaDirectory.ShouldBe(elsewhere); paths.BlobDirectory.ShouldStartWith(elsewhere); paths.MediaIndexFile.ShouldStartWith(elsewhere); paths.MediaTempDirectory.ShouldStartWith(elsewhere); } [Fact] public void The_staging_area_is_a_sibling_of_the_blobs() { // Promotion has to be a rename, not a cross-volume copy of tens of megabytes. var paths = new AppPaths(_root, Path.Combine(_root, "archive")); Path.GetDirectoryName(paths.MediaTempDirectory).ShouldBe(Path.GetDirectoryName(paths.BlobDirectory)); } [Fact] public void An_omitted_media_root_falls_back_to_the_data_directory() { // The two-argument form is what tests and the override path use; without a media root it // must stay inside the directory it was given rather than escaping to the real profile. var paths = new AppPaths(_root); paths.MediaDirectory.ShouldBe(Path.Combine(_root, "media")); } [Fact] public void Creating_the_directories_is_idempotent() { var paths = new AppPaths(_root, Path.Combine(_root, "archive")); paths.EnsureCreated(); paths.EnsureCreated(); Directory.Exists(paths.BlobDirectory).ShouldBeTrue(); Directory.Exists(paths.ShowcaseDirectory).ShouldBeTrue(); Directory.Exists(paths.MediaTempDirectory).ShouldBeTrue(); Directory.Exists(paths.LogDirectory).ShouldBeTrue(); } }