135 lines
4.6 KiB
C#
135 lines
4.6 KiB
C#
using Microsoft.Extensions.Configuration;
|
|
using PLib.Application.Library;
|
|
using PLib.Desktop.Services;
|
|
using PLib.Desktop.Settings;
|
|
using PLib.Infrastructure.Storage;
|
|
using Shouldly;
|
|
|
|
namespace PLib.Tests.Settings;
|
|
|
|
/// <summary>
|
|
/// The settings file is not just storage — it is a live configuration source. These tests
|
|
/// close the loop: what the store writes has to be what the options binder reads back.
|
|
/// </summary>
|
|
public sealed class AppSettingsStoreTests : IDisposable
|
|
{
|
|
private readonly TempPaths _paths = new();
|
|
|
|
public void Dispose() => _paths.Dispose();
|
|
|
|
[Fact]
|
|
public async Task Saved_settings_are_readable_by_the_configuration_binder()
|
|
{
|
|
var settings = new AppSettings
|
|
{
|
|
Folders = [@"C:\videos", @"D:\more videos"],
|
|
ThumbnailWidth = 640,
|
|
ThumbnailPositionRatio = 0.25,
|
|
MaxIndexingConcurrency = 8,
|
|
MinimumFileSizeInBytes = 2_097_152,
|
|
Theme = ThemeMode.Light,
|
|
};
|
|
|
|
await new JsonAppSettingsStore(_paths).SaveAsync(settings, Token);
|
|
|
|
var (library, appearance) = Reload();
|
|
|
|
library.Folders.ShouldBe(settings.Folders);
|
|
library.ThumbnailWidth.ShouldBe(640);
|
|
library.ThumbnailPositionRatio.ShouldBe(0.25);
|
|
library.MaxIndexingConcurrency.ShouldBe(8);
|
|
library.MinimumFileSizeInBytes.ShouldBe(2_097_152);
|
|
appearance.Theme.ShouldBe(ThemeMode.Light);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Removing_a_folder_actually_shortens_the_stored_list()
|
|
{
|
|
var store = new JsonAppSettingsStore(_paths);
|
|
var settings = Sample with { Folders = [@"C:\a", @"C:\b", @"C:\c"] };
|
|
|
|
await store.SaveAsync(settings, Token);
|
|
await store.SaveAsync(settings with { Folders = [@"C:\a", @"C:\c"] }, Token);
|
|
|
|
// Configuration merges arrays by index, so a shorter list is the case most likely
|
|
// to leave a stale entry behind.
|
|
Reload().Library.Folders.ShouldBe([@"C:\a", @"C:\c"]);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Keys_the_settings_screen_does_not_know_about_survive_a_save()
|
|
{
|
|
await File.WriteAllTextAsync(
|
|
Path.Combine(_paths.DataDirectory, "settings.json"),
|
|
"""{ "Library": { "VideoExtensions": [ ".mp4" ] }, "Experimental": { "Flag": true } }""",
|
|
Token);
|
|
|
|
await new JsonAppSettingsStore(_paths).SaveAsync(Sample, Token);
|
|
|
|
var configuration = Build();
|
|
configuration["Experimental:Flag"].ShouldBe("True");
|
|
configuration["Library:VideoExtensions:0"].ShouldBe(".mp4");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void Only_changes_that_affect_the_contents_of_the_library_ask_for_a_rescan(bool cosmeticOnly)
|
|
{
|
|
var changed = cosmeticOnly
|
|
? Sample with { ThumbnailWidth = 999, Theme = ThemeMode.Dark }
|
|
: Sample with { Folders = [@"C:\elsewhere"] };
|
|
|
|
changed.RequiresRescanComparedTo(Sample).ShouldBe(!cosmeticOnly);
|
|
}
|
|
|
|
private static CancellationToken Token => TestContext.Current.CancellationToken;
|
|
|
|
private static AppSettings Sample => new()
|
|
{
|
|
Folders = [@"C:\videos"],
|
|
ThumbnailWidth = 480,
|
|
ThumbnailPositionRatio = 0.15,
|
|
MaxIndexingConcurrency = 4,
|
|
MinimumFileSizeInBytes = 65_536,
|
|
Theme = ThemeMode.System,
|
|
};
|
|
|
|
private IConfigurationRoot Build() => new ConfigurationBuilder()
|
|
.AddJsonFile(Path.Combine(_paths.DataDirectory, "settings.json"), optional: false)
|
|
.Build();
|
|
|
|
private (LibraryOptions Library, AppearanceOptions Appearance) Reload()
|
|
{
|
|
var configuration = Build();
|
|
|
|
var library = new LibraryOptions();
|
|
configuration.GetSection(LibraryOptions.SectionName).Bind(library);
|
|
|
|
var appearance = new AppearanceOptions();
|
|
configuration.GetSection(AppearanceOptions.SectionName).Bind(appearance);
|
|
|
|
return (library, appearance);
|
|
}
|
|
|
|
private sealed class TempPaths : IAppPaths, IDisposable
|
|
{
|
|
public TempPaths()
|
|
{
|
|
DataDirectory = Path.Combine(Path.GetTempPath(), $"plib-tests-{Guid.CreateVersion7()}");
|
|
ThumbnailDirectory = Path.Combine(DataDirectory, "thumbnails");
|
|
DatabaseFile = Path.Combine(DataDirectory, "library.db");
|
|
|
|
Directory.CreateDirectory(ThumbnailDirectory);
|
|
}
|
|
|
|
public string DataDirectory { get; }
|
|
|
|
public string ThumbnailDirectory { get; }
|
|
|
|
public string DatabaseFile { get; }
|
|
|
|
public void Dispose() => Directory.Delete(DataDirectory, recursive: true);
|
|
}
|
|
}
|