Files
PLib/tests/PLib.Tests/Settings/SettingsViewModelTests.cs
T

108 lines
3.9 KiB
C#

using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using NSubstitute;
using PLib.Application.Library;
using PLib.Desktop.Services;
using PLib.Desktop.Settings;
using PLib.Desktop.ViewModels;
using Shouldly;
namespace PLib.Tests.Settings;
public sealed class SettingsViewModelTests
{
private readonly IAppSettingsStore _store = Substitute.For<IAppSettingsStore>();
[Fact]
public async Task Opening_and_saving_without_touching_anything_changes_nothing()
{
// Both of these are displayed in a lossier unit than they are stored in: 65 536 bytes
// shows as 0,06 MB. Converting the untouched field back used to yield 62 915, which
// silently rewrote the setting and forced a full rescan on every visit to the panel.
var options = new LibraryOptions
{
Folders = [@"C:\videos"],
MinimumFileSizeInBytes = 65_536,
ThumbnailPositionRatio = 0.15,
};
var (viewModel, outcome) = await SaveAsync(options);
outcome.RescanRequired.ShouldBeFalse();
Written.MinimumFileSizeInBytes.ShouldBe(65_536);
Written.ThumbnailPositionRatio.ShouldBe(0.15);
viewModel.HasFolders.ShouldBeTrue();
}
[Fact]
public async Task Editing_the_minimum_size_does_write_the_new_value()
{
var (_, outcome) = await SaveAsync(
new LibraryOptions { Folders = [@"C:\videos"], MinimumFileSizeInBytes = 65_536 },
viewModel => viewModel.MinimumFileSizeMegabytes = 4);
Written.MinimumFileSizeInBytes.ShouldBe(4 * 1024 * 1024);
outcome.RescanRequired.ShouldBeTrue();
}
[Fact]
public async Task Removing_a_folder_is_carried_into_the_saved_settings()
{
var (_, outcome) = await SaveAsync(
new LibraryOptions { Folders = [@"C:\a", @"C:\b"] },
viewModel => viewModel.Folders[0].RemoveCommand.Execute().Subscribe());
Written.Folders.ShouldBe([@"C:\b"]);
outcome.RescanRequired.ShouldBeTrue();
}
[Fact]
public async Task Cancelling_writes_nothing()
{
var viewModel = Create(new LibraryOptions { Folders = [@"C:\videos"] });
var closed = viewModel.Closed.FirstAsync().ToTask();
viewModel.MinimumFileSizeMegabytes = 999;
await viewModel.CancelCommand.Execute().FirstAsync().ToTask(TestContext.Current.CancellationToken);
(await closed).Saved.ShouldBeFalse();
_store.ReceivedCalls().ShouldBeEmpty();
}
private AppSettings Written =>
(AppSettings)_store.ReceivedCalls().Single(call => call.GetMethodInfo().Name == nameof(IAppSettingsStore.SaveAsync))
.GetArguments()[0]!;
private async Task<(SettingsViewModel ViewModel, SettingsDialogOutcome Outcome)> SaveAsync(
LibraryOptions options,
Action<SettingsViewModel>? edit = null)
{
var viewModel = Create(options);
var closed = viewModel.Closed.FirstAsync().ToTask();
edit?.Invoke(viewModel);
await viewModel.SaveCommand.Execute().FirstAsync().ToTask(TestContext.Current.CancellationToken);
return (viewModel, await closed);
}
private SettingsViewModel Create(LibraryOptions options) => new(
Substitute.For<IServiceScopeFactory>(),
Monitor(options),
Monitor(new AppearanceOptions()),
_store,
Substitute.For<IFolderPicker>(),
Substitute.For<IThemeService>(),
NullLogger<SettingsViewModel>.Instance);
private static IOptionsMonitor<T> Monitor<T>(T value)
{
var monitor = Substitute.For<IOptionsMonitor<T>>();
monitor.CurrentValue.Returns(value);
return monitor;
}
}