using System; using System.Threading.Tasks; using FluentAssertions; using ImageCatalog_2; using ImageCatalog_2.Services; using MaddoShared; using Microsoft.Extensions.Logging; using Moq; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace MaddoShared.Tests; [TestClass] public class DataModelCharacterizationTests { [TestMethod] public void SelectSourceFolderCommand_RaisesEvent() { var model = CreateModel(); var raised = false; model.SelectSourceFolderRequested += (_, _) => raised = true; model.SelectSourceFolderCommand.Execute(null); raised.Should().BeTrue(); } [TestMethod] public async Task SaveSettingsToFileAsync_DelegatesToSettingsService() { var settingsService = new Mock(); settingsService .Setup(s => s.SaveSettingsAsync(It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); var model = CreateModel(settingsService: settingsService.Object); await model.SaveSettingsToFileAsync("settings.xml"); settingsService.Verify( s => s.SaveSettingsAsync("settings.xml", model), Times.Once); } [TestMethod] public async Task LoadSettingsFromFileAsync_DelegatesToSettingsService() { var settingsService = new Mock(); settingsService .Setup(s => s.LoadSettingsAsync(It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); var model = CreateModel(settingsService: settingsService.Object); await model.LoadSettingsFromFileAsync("settings.xml"); settingsService.Verify( s => s.LoadSettingsAsync("settings.xml", model), Times.Once); } [TestMethod] public void ThumbnailOptionIndex_UpdatesAuthoritativeThumbnailState() { var model = CreateModel(); model.ThumbnailOptionIndex = (int)DataModel.ThumbnailOptionEnum.RaceTime; model.ThumbnailOption.Should().Be(DataModel.ThumbnailOptionEnum.RaceTime); model.AddRaceTimeToThumbnails.Should().BeTrue(); model.ThumbnailMode.Should().Be("RaceTime"); } [TestMethod] public void ProcessingChildChange_RaisesDataModelPropertyChanged() { var model = CreateModel(); string? changed = null; model.PropertyChanged += (_, args) => changed = args.PropertyName; model.Processing.SpeedCounter = "12.00 f/s"; changed.Should().Be(nameof(DataModel.SpeedCounter)); model.SpeedCounter.Should().Be("12.00 f/s"); } [TestMethod] public void PathsNormalize_UpdatesFlattenedSourceAndDestination() { var model = CreateModel(); model.SourcePath = "\"C:/input\""; model.DestinationPath = "C:/output"; model.Paths.NormalizePaths(); model.SourcePath.Should().Be($"C:{System.IO.Path.DirectorySeparatorChar}input{System.IO.Path.DirectorySeparatorChar}"); model.DestinationPath.Should().Be($"C:{System.IO.Path.DirectorySeparatorChar}output{System.IO.Path.DirectorySeparatorChar}"); } [TestMethod] public void AiChildChange_RaisesDataModelPropertyChanged() { var model = CreateModel(); string? changed = null; model.PropertyChanged += (_, args) => changed = args.PropertyName; model.Ai.ModelsFolderPath = "K:/models"; changed.Should().Be(nameof(DataModel.ModelsFolderPath)); model.ModelsFolderPath.Should().Be("K:/models"); } [TestMethod] public void RaceUploadChildChange_RaisesDataModelPropertyChanged() { var model = CreateModel(); string? changed = null; model.PropertyChanged += (_, args) => changed = args.PropertyName; model.RaceUpload.ApiLogin = "admin"; changed.Should().Be(nameof(DataModel.ApiLogin)); model.ApiLogin.Should().Be("admin"); } [TestMethod] public void VisualChildChange_RaisesDataModelPropertyChanged() { var model = CreateModel(); string? changed = null; model.PropertyChanged += (_, args) => changed = args.PropertyName; model.Visual.FontSize = 42; changed.Should().Be(nameof(DataModel.FontSize)); model.FontSize.Should().Be(42); } private static DataModel CreateModel( ISettingsService? settingsService = null, ITestService? testService = null) { var mapper = new Mock().Object; var picSettings = new PicSettings(); var imageCreator = new Mock(); imageCreator .Setup(x => x.CreateImageAsync(It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); var imageCreationService = new ImageCreationService( new Mock>().Object, picSettings, imageCreator.Object); var imageProcessingCoordinator = new ImageProcessingCoordinator( imageCreationService, new Mock>().Object); var aiExtractionService = new AiExtractionService( new Mock>().Object); return new DataModel( testService ?? new Mock().Object, settingsService ?? new Mock().Object, imageCreationService, aiExtractionService, imageProcessingCoordinator, picSettings, mapper, new Mock>().Object, versionProvider: null); } }