releases/tests/Paca.Tests/Infrastructure/SettingsViewModelTests.cs

141 lines
4 KiB
C#

using Paca.App.ViewModels;
using Paca.Core.Config;
using Xunit;
namespace Paca.Tests.Infrastructure;
public sealed class SettingsViewModelTests
{
[Fact]
public void LoadFromConfig_MapsAllPropertiesAccurately()
{
var config = new AppConfig
{
Theme = "light",
AccentColor = "#2563EB",
Concurrency = 16,
MaxConcurrentDownloads = 5,
OutputFolder = @"C:\Downloads\Videos",
ToastDurationMs = 4500,
ReduceMotion = true
};
var vm = new SettingsViewModel(config);
Assert.Equal("light", vm.Theme);
Assert.Equal("#2563EB", vm.AccentColor);
Assert.Equal(16, vm.Concurrency);
Assert.Equal(5, vm.MaxConcurrentDownloads);
Assert.Equal(@"C:\Downloads\Videos", vm.OutputFolder);
Assert.Equal(4500, vm.ToastDurationMs);
Assert.True(vm.ReduceMotion);
Assert.False(vm.IsDirty);
Assert.Equal(0, vm.DirtyCount);
}
[Fact]
public void PropertyChanged_TracksDirtyStateAccurately()
{
var config = new AppConfig();
var vm = new SettingsViewModel(config);
Assert.False(vm.IsDirty);
vm.Concurrency = 32;
Assert.True(vm.IsDirty);
Assert.True(vm.DirtyCount >= 1);
// 원본 값으로 복구하면 IsDirty 해제
vm.Concurrency = config.Concurrency;
Assert.False(vm.IsDirty);
Assert.Equal(0, vm.DirtyCount);
}
[Fact]
public void Validate_CatchesInvalidInputs()
{
var config = new AppConfig();
var vm = new SettingsViewModel(config);
Assert.True(vm.Validate());
Assert.False(vm.HasErrors);
// 1. 유효하지 않은 세그먼트 동시 수
vm.Concurrency = 0;
Assert.False(vm.Validate());
Assert.True(vm.HasErrors);
Assert.Contains("세그먼트", vm.ValidationSummary);
vm.Concurrency = 8;
Assert.True(vm.Validate());
// 2. 유효하지 않은 토스트 지속시간
vm.ToastDurationMs = 100;
Assert.False(vm.Validate());
Assert.True(vm.HasErrors);
vm.ToastDurationMs = 3000;
Assert.True(vm.Validate());
// 3. 유효하지 않은 강조색 포맷
vm.AccentColor = "InvalidHex";
Assert.False(vm.Validate());
Assert.True(vm.HasErrors);
vm.AccentColor = "#6366F1";
Assert.True(vm.Validate());
// 4. 유효하지 않은 예약 시간 포맷
vm.DownloadScheduleWindow = "25:99-99:00";
Assert.False(vm.Validate());
Assert.True(vm.HasErrors);
vm.DownloadScheduleWindow = "02:00-08:00";
Assert.True(vm.Validate());
}
[Fact]
public void CommitToConfig_UpdatesTargetConfigCompletely()
{
var sourceConfig = new AppConfig();
var vm = new SettingsViewModel(sourceConfig)
{
Theme = "highcontrast",
AccentColor = "#34D399",
Concurrency = 12,
MaxConcurrentDownloads = 6,
OutputFolder = @"D:\Media\Saved",
ReduceMotion = true,
AutoStart = true
};
var target = new AppConfig();
vm.CommitToConfig(target);
Assert.Equal("highcontrast", target.Theme);
Assert.Equal("#34D399", target.AccentColor);
Assert.Equal(12, target.Concurrency);
Assert.Equal(6, target.MaxConcurrentDownloads);
Assert.Equal(@"D:\Media\Saved", target.OutputFolder);
Assert.True(target.ReduceMotion);
Assert.True(target.AutoStart);
}
[Fact]
public void ResetToDefaults_RestoresStandardDefaults()
{
var config = new AppConfig
{
Theme = "light",
Concurrency = 32,
MaxConcurrentDownloads = 10
};
var vm = new SettingsViewModel(config);
vm.ResetToDefaults();
Assert.Equal("dark", vm.Theme);
Assert.Equal(8, vm.Concurrency);
Assert.Equal(3, vm.MaxConcurrentDownloads);
}
}