diff --git a/AudioCuesheetEditor/Extensions/SessionStateContainer.cs b/AudioCuesheetEditor/Extensions/SessionStateContainer.cs index 82035a6d..1a988975 100644 --- a/AudioCuesheetEditor/Extensions/SessionStateContainer.cs +++ b/AudioCuesheetEditor/Extensions/SessionStateContainer.cs @@ -93,29 +93,18 @@ public void ResetImport() { Importfile = null; ImportAudiofile = null; - } - - public void StartImportCuesheet(ApplicationOptions applicationOptions) - { - if (ImportCuesheet != null) - { - Cuesheet.Import(ImportCuesheet, applicationOptions, _traceChangeManager); - ImportCuesheet = null; - } - ResetImport(); + ImportCuesheet = null; } private void SetCuesheetReference(Cuesheet value) { - cuesheet.CuesheetImported -= Cuesheet_CuesheetImported; cuesheet = value; - cuesheet.CuesheetImported += Cuesheet_CuesheetImported; _traceChangeManager.Reset(); _traceChangeManager.TraceChanges(Cuesheet); CuesheetChanged?.Invoke(this, EventArgs.Empty); } - private void Cuesheet_CuesheetImported(object? sender, EventArgs e) + public void FireCuesheetImported() { CuesheetChanged?.Invoke(this, EventArgs.Empty); } diff --git a/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs b/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs index dfcbf18d..755f4d14 100644 --- a/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs +++ b/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs @@ -13,9 +13,7 @@ //You should have received a copy of the GNU General Public License //along with Foobar. If not, see //. -using AudioCuesheetEditor.Model.AudioCuesheet.Import; using AudioCuesheetEditor.Model.Entity; -using AudioCuesheetEditor.Model.IO; using AudioCuesheetEditor.Model.IO.Audio; using AudioCuesheetEditor.Model.IO.Export; using AudioCuesheetEditor.Model.Options; @@ -60,7 +58,6 @@ public class Cuesheet(TraceChangeManager? traceChangeManager = null) : Validatea public event EventHandler? TrackRemoved; public event EventHandler? SectionAdded; public event EventHandler? SectionRemoved; - public event EventHandler? CuesheetImported; [JsonInclude] public IReadOnlyCollection Tracks @@ -174,7 +171,7 @@ public TimeSpan? RecordingTime } [JsonIgnore] - public Boolean IsImporting { get; private set; } + public Boolean IsImporting { get; set; } [JsonInclude] public IReadOnlyCollection Sections @@ -391,27 +388,6 @@ public void MoveTrack(Track track, MoveDirection moveDirection) } } - public void Import(ICuesheet cuesheet, ApplicationOptions applicationOptions, TraceChangeManager? traceChangeManager = null) - { - //Since we use a stack for several changes we need to lock execution for everything else - lock (syncLock) - { - IsImporting = true; - //We are doing a bulk edit, so inform the TraceChangeManager - if (traceChangeManager != null) - { - traceChangeManager.BulkEdit = true; - } - CopyValues(cuesheet, applicationOptions); - if (traceChangeManager != null) - { - traceChangeManager.BulkEdit = false; - } - IsImporting = false; - } - CuesheetImported?.Invoke(this, EventArgs.Empty); - } - public void StartRecording() { recordingStart = DateTime.UtcNow; @@ -552,60 +528,6 @@ private void ReCalculateTrackProperties(Track trackToCalculate) } } - /// - /// Copy values from import cuesheet to this cuesheet - /// - /// Reference to import cuesheet - /// Reference to application options - private void CopyValues(ICuesheet cuesheet, ApplicationOptions applicationOptions) - { - Artist = cuesheet.Artist; - Title = cuesheet.Title; - IEnumerable? tracks = null; - if (cuesheet is Cuesheet originCuesheet) - { - tracks = originCuesheet.tracks; - // Copy sections - foreach (var section in originCuesheet.Sections) - { - var newSplitPoint = AddSection(); - newSplitPoint.CopyValues(section); - } - Audiofile = originCuesheet.Audiofile; - CDTextfile = originCuesheet.CDTextfile; - Cataloguenumber = originCuesheet.Cataloguenumber; - } - if (cuesheet is ImportCuesheet importCuesheet) - { - tracks = importCuesheet.Tracks; - if (String.IsNullOrEmpty(importCuesheet.Audiofile) == false) - { - Audiofile = new Audiofile(importCuesheet.Audiofile); - } - if (String.IsNullOrEmpty(importCuesheet.CDTextfile) == false) - { - CDTextfile = new CDTextfile(importCuesheet.CDTextfile); - } - Cataloguenumber = new Cataloguenumber() - { - Value = importCuesheet.Cataloguenumber - }; - } - if (tracks != null) - { - foreach (var importTrack in tracks) - { - //We don't want to copy the cuesheet reference since we are doing a copy and want to assign the track to this object - var track = new Track(importTrack, false); - AddTrack(track, applicationOptions); - } - } - else - { - throw new NullReferenceException(); - } - } - private void Track_RankPropertyValueChanged(object? sender, string e) { if (sender is Track trackRaisedEvent) diff --git a/AudioCuesheetEditor/Model/UI/TraceChangeManager.cs b/AudioCuesheetEditor/Model/UI/TraceChangeManager.cs index 78b5ca1c..a4321ad1 100644 --- a/AudioCuesheetEditor/Model/UI/TraceChangeManager.cs +++ b/AudioCuesheetEditor/Model/UI/TraceChangeManager.cs @@ -13,28 +13,15 @@ //You should have received a copy of the GNU General Public License //along with Foobar. If not, see //. -using AudioCuesheetEditor.Model.AudioCuesheet; -using AudioCuesheetEditor.Pages; -using Markdig.Extensions.Yaml; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - namespace AudioCuesheetEditor.Model.UI { /// /// Class for tracing changes on an object /// - public class TracedChange + public class TracedChange(ITraceable traceableObject, TraceableChange traceableChange) { - private readonly WeakReference _tracedObject; - public TracedChange(ITraceable traceableObject, TraceableChange traceableChange) - { - _tracedObject = new WeakReference(traceableObject, false); - TraceableChange = traceableChange; - } + private readonly WeakReference _tracedObject = new(traceableObject, false); + public ITraceable? TraceableObject { get @@ -47,26 +34,21 @@ public ITraceable? TraceableObject } } - public TraceableChange TraceableChange { get; } + public TraceableChange TraceableChange { get; } = traceableChange; } - public class TracedChanges + public class TracedChanges(IEnumerable changes) { - public TracedChanges(IEnumerable changes) - { - Changes = new(changes); - } - - public List Changes { get; } + public List Changes { get; } = new(changes); public Boolean HasTraceableObject { get { return Changes.Any(x => x.TraceableObject != null); } } } /// /// Manager for Undo and Redo operations on objects. /// - public class TraceChangeManager + public class TraceChangeManager(ILogger logger) { - private readonly ILogger _logger; + private readonly ILogger _logger = logger; private readonly Stack undoStack = new(); private readonly Stack redoStack = new(); @@ -77,7 +59,7 @@ public class TraceChangeManager public event EventHandler? UndoDone; public event EventHandler? RedoDone; - public Boolean CurrentlyHandlingRedoOrUndoChanges { get; private set; } + public Boolean CurrentlyHandlingRedoOrUndoChanges { get; private set; } = false; /// /// Is Undo() currently possible (are there any changes)? /// @@ -100,12 +82,6 @@ public Boolean CanRedo } } - public TraceChangeManager(ILogger logger) - { - CurrentlyHandlingRedoOrUndoChanges = false; - _logger = logger; - } - public void TraceChanges(ITraceable traceable) { traceable.TraceablePropertyChanged += Traceable_TraceablePropertyChanged; @@ -229,7 +205,7 @@ public Boolean BulkEdit _logger.LogDebug("Set BulkEdit called with {value}", value); if (value) { - bulkEditTracedChanges = new(); + bulkEditTracedChanges = []; } else { @@ -293,7 +269,7 @@ private void Traceable_TraceablePropertyChanged(object? sender, TraceablePropert if (BulkEdit == false) { //Single change - var changes = new TracedChanges(new List() { new((ITraceable)sender, e.TraceableChange) }); + var changes = new TracedChanges([new((ITraceable)sender, e.TraceableChange)]); undoStack.Push(changes); redoStack.Clear(); TracedObjectHistoryChanged?.Invoke(this, EventArgs.Empty); diff --git a/AudioCuesheetEditor/Pages/ViewModeImport.razor b/AudioCuesheetEditor/Pages/ViewModeImport.razor index ae38f0f2..03cc51b3 100644 --- a/AudioCuesheetEditor/Pages/ViewModeImport.razor +++ b/AudioCuesheetEditor/Pages/ViewModeImport.razor @@ -400,8 +400,7 @@ along with Foobar. If not, see private async Task ImportData() { - var options = await _localStorageOptionsProvider.GetOptions(); - _sessionStateContainer.StartImportCuesheet(options); + await _importManager.ImportCuesheetAsync(); _sessionStateContainer.CurrentViewMode = ViewMode.ViewModeFull; StateHasChanged(); } diff --git a/AudioCuesheetEditor/Services/IO/ImportManager.cs b/AudioCuesheetEditor/Services/IO/ImportManager.cs index e30e1206..09acd171 100644 --- a/AudioCuesheetEditor/Services/IO/ImportManager.cs +++ b/AudioCuesheetEditor/Services/IO/ImportManager.cs @@ -16,8 +16,11 @@ using AudioCuesheetEditor.Data.Options; using AudioCuesheetEditor.Extensions; using AudioCuesheetEditor.Model.AudioCuesheet; +using AudioCuesheetEditor.Model.AudioCuesheet.Import; using AudioCuesheetEditor.Model.IO; +using AudioCuesheetEditor.Model.IO.Audio; using AudioCuesheetEditor.Model.Options; +using AudioCuesheetEditor.Model.UI; using AudioCuesheetEditor.Model.Utility; using Blazorise; @@ -31,11 +34,12 @@ public enum ImportFileType Textfile, Audiofile } - public class ImportManager(SessionStateContainer sessionStateContainer, ILocalStorageOptionsProvider localStorageOptionsProvider, TextImportService textImportService) + public class ImportManager(SessionStateContainer sessionStateContainer, ILocalStorageOptionsProvider localStorageOptionsProvider, TextImportService textImportService, TraceChangeManager traceChangeManager) { private readonly SessionStateContainer _sessionStateContainer = sessionStateContainer; private readonly ILocalStorageOptionsProvider _localStorageOptionsProvider = localStorageOptionsProvider; private readonly TextImportService _textImportService = textImportService; + private readonly TraceChangeManager _traceChangeManager = traceChangeManager; public async Task> ImportFilesAsync(IEnumerable files) { @@ -88,21 +92,28 @@ public async Task ImportTextAsync(IEnumerable fileContent) _sessionStateContainer.Importfile = _textImportService.Analyse(options, fileContent); if (_sessionStateContainer.Importfile.AnalysedCuesheet != null) { - var applicationOptions = await _localStorageOptionsProvider.GetOptions(); var importCuesheet = new Cuesheet(); - importCuesheet.Import(_sessionStateContainer.Importfile.AnalysedCuesheet, applicationOptions); + await CopyCuesheetAsync(importCuesheet, _sessionStateContainer.Importfile.AnalysedCuesheet); _sessionStateContainer.ImportCuesheet = importCuesheet; } } + public async Task ImportCuesheetAsync() + { + if (_sessionStateContainer.ImportCuesheet != null) + { + await CopyCuesheetAsync(_sessionStateContainer.Cuesheet, _sessionStateContainer.ImportCuesheet); + } + _sessionStateContainer.ResetImport(); + } + private async Task ImportCuesheetAsync(IEnumerable fileContent) { _sessionStateContainer.Importfile = CuesheetImportService.Analyse(fileContent); if (_sessionStateContainer.Importfile.AnalysedCuesheet != null) { - var applicationOptions = await _localStorageOptionsProvider.GetOptions(); var importCuesheet = new Cuesheet(); - importCuesheet.Import(_sessionStateContainer.Importfile.AnalysedCuesheet, applicationOptions); + await CopyCuesheetAsync(importCuesheet, _sessionStateContainer.Importfile.AnalysedCuesheet); _sessionStateContainer.ImportCuesheet = importCuesheet; } } @@ -115,5 +126,60 @@ private static async Task ReadFileContentAsync(IFileEntry file) stream.Close(); return fileContent; } + + private async Task CopyCuesheetAsync(Cuesheet target, ICuesheet cuesheetToCopy) + { + _traceChangeManager.BulkEdit = true; + target.IsImporting = true; + target.Artist = cuesheetToCopy.Artist; + target.Title = cuesheetToCopy.Title; + IEnumerable? tracks = null; + if (cuesheetToCopy is Cuesheet originCuesheet) + { + tracks = originCuesheet.Tracks; + // Copy sections + foreach (var section in originCuesheet.Sections) + { + var newSplitPoint = target.AddSection(); + newSplitPoint.CopyValues(section); + } + target.Audiofile = originCuesheet.Audiofile; + target.CDTextfile = originCuesheet.CDTextfile; + target.Cataloguenumber = originCuesheet.Cataloguenumber; + } + if (cuesheetToCopy is ImportCuesheet importCuesheet) + { + tracks = importCuesheet.Tracks; + if (String.IsNullOrEmpty(importCuesheet.Audiofile) == false) + { + target.Audiofile = new Audiofile(importCuesheet.Audiofile); + } + if (String.IsNullOrEmpty(importCuesheet.CDTextfile) == false) + { + target.CDTextfile = new CDTextfile(importCuesheet.CDTextfile); + } + target.Cataloguenumber = new Cataloguenumber() + { + Value = importCuesheet.Cataloguenumber + }; + } + if (tracks != null) + { + var applicationOptions = await _localStorageOptionsProvider.GetOptions(); + foreach (var importTrack in tracks) + { + //We don't want to copy the cuesheet reference since we are doing a copy and want to assign the track to this object + var track = new Track(importTrack, false); + target.AddTrack(track, applicationOptions); + } + } + else + { + throw new NullReferenceException(); + } + target.IsImporting = false; + _traceChangeManager.BulkEdit = false; + _sessionStateContainer.FireCuesheetImported(); + } } } diff --git a/AudioCuesheetEditorTests/Extensions/SessionStateContainerTests.cs b/AudioCuesheetEditorTests/Extensions/SessionStateContainerTests.cs index 87b97a64..c18c1854 100644 --- a/AudioCuesheetEditorTests/Extensions/SessionStateContainerTests.cs +++ b/AudioCuesheetEditorTests/Extensions/SessionStateContainerTests.cs @@ -43,7 +43,7 @@ public void SessionStateContainerFireCuesheetChangedTest() cuesheetChangedFired = true; }; Assert.IsFalse(cuesheetChangedFired); - container.Cuesheet.Import(new Cuesheet(), helper.ApplicationOptions); + container.FireCuesheetImported(); Assert.IsTrue(cuesheetChangedFired); } } diff --git a/AudioCuesheetEditorTests/Model/AudioCuesheet/CuesheetTests.cs b/AudioCuesheetEditorTests/Model/AudioCuesheet/CuesheetTests.cs index b150554b..00373876 100644 --- a/AudioCuesheetEditorTests/Model/AudioCuesheet/CuesheetTests.cs +++ b/AudioCuesheetEditorTests/Model/AudioCuesheet/CuesheetTests.cs @@ -247,23 +247,22 @@ public async Task ImportTestAsync() }; localStorageOptionsProviderMock.Setup(x => x.GetOptions()).ReturnsAsync(importOptions); var textImportService = new TextImportService(); - var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, textImportService); - await importManager.ImportTextAsync(fileContent); + var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, textImportService, traceChangeManager); var testHelper = new TestHelper(); // Act - sessionStateContainer.StartImportCuesheet(testHelper.ApplicationOptions); + await importManager.ImportTextAsync(fileContent); // Assert - Assert.IsNull(sessionStateContainer.Cuesheet.CDTextfile); - Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.Cuesheet.Validate().Status); - Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.Cuesheet.Tracks.ElementAt(0).Validate().Status); - Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.Cuesheet.Tracks.ElementAt(1).Validate().Status); - Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.Cuesheet.Tracks.ElementAt(2).Validate().Status); - Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.Cuesheet.Tracks.ElementAt(3).Validate().Status); - Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.Cuesheet.Tracks.ElementAt(4).Validate().Status); - Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.Cuesheet.Tracks.ElementAt(5).Validate().Status); - Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.Cuesheet.Tracks.ElementAt(6).Validate().Status); - Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.Cuesheet.Tracks.ElementAt(7).Validate().Status); + Assert.IsNull(sessionStateContainer.ImportCuesheet?.CDTextfile); + Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Validate().Status); + Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(0).Validate().Status); + Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(1).Validate().Status); + Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(2).Validate().Status); + Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(3).Validate().Status); + Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(4).Validate().Status); + Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(5).Validate().Status); + Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(6).Validate().Status); + Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(7).Validate().Status); } [TestMethod()] @@ -285,19 +284,16 @@ public async Task ImportTestCalculateEndCorrectlyAsync() var importOptions = new ImportOptions(); importOptions.TextImportScheme.SchemeCuesheet = null; localStorageOptionsProviderMock.Setup(x => x.GetOptions()).ReturnsAsync(importOptions); - var textImportService = new TextImportService();; - var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, textImportService); - await importManager.ImportTextAsync(fileContent); - var cuesheet = new Cuesheet(); + var textImportService = new TextImportService(); + var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, textImportService, traceChangeManager); // Act - cuesheet.Import(sessionStateContainer.ImportCuesheet!, testHelper.ApplicationOptions); + await importManager.ImportTextAsync(fileContent); // Assert Assert.IsNull(sessionStateContainer.Importfile?.AnalyseException); Assert.IsNotNull(sessionStateContainer.ImportCuesheet); Assert.AreEqual(39, sessionStateContainer.ImportCuesheet.Tracks.Count); - Assert.AreEqual(39, cuesheet.Tracks.Count); - Assert.AreEqual(new TimeSpan(0, 5, 24), cuesheet.Tracks.ElementAt(0).End); - Assert.AreEqual(new TimeSpan(3, 13, 13), cuesheet.Tracks.ElementAt(38).Begin); + Assert.AreEqual(new TimeSpan(0, 5, 24), sessionStateContainer.ImportCuesheet.Tracks.ElementAt(0).End); + Assert.AreEqual(new TimeSpan(3, 13, 13), sessionStateContainer.ImportCuesheet.Tracks.ElementAt(38).Begin); } [TestMethod()] @@ -590,22 +586,16 @@ public async Task ImportSamplesTestAsync() }; localStorageOptionsProviderMock.Setup(x => x.GetOptions()).ReturnsAsync(importOptions); var textImportService = new TextImportService(); - var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, textImportService); - await importManager.ImportTextAsync(fileContent); - var cuesheet = new Cuesheet - { - Artist = "Testartist", - Title = "Testtitle" - }; + var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, textImportService, traceChangeManager); // Act - cuesheet.Import(sessionStateContainer.ImportCuesheet!, testHelper.ApplicationOptions); + await importManager.ImportTextAsync(fileContent); // Assert Assert.IsNull(sessionStateContainer.Importfile?.AnalyseException); Assert.IsNotNull(sessionStateContainer.ImportCuesheet); - Assert.AreEqual("CuesheetArtist", cuesheet.Artist); - Assert.AreEqual("CuesheetTitle", cuesheet.Title); - Assert.AreEqual(8, cuesheet.Tracks.Count); - Assert.AreEqual(new TimeSpan(1, 15, 54), cuesheet.Tracks.Last().End); + Assert.AreEqual("CuesheetArtist", sessionStateContainer.ImportCuesheet.Artist); + Assert.AreEqual("CuesheetTitle", sessionStateContainer.ImportCuesheet.Title); + Assert.AreEqual(8, sessionStateContainer.ImportCuesheet.Tracks.Count); + Assert.AreEqual(new TimeSpan(1, 15, 54), sessionStateContainer.ImportCuesheet.Tracks.Last().End); } [TestMethod()] @@ -619,24 +609,18 @@ public async Task ImportSamples2TestAsync() var localStorageOptionsProviderMock = new Mock(); var importOptions = new ImportOptions(); importOptions.TextImportScheme.SchemeCuesheet = null; - localStorageOptionsProviderMock.Setup(x => x.GetOptions()).ReturnsAsync(new ImportOptions()); + localStorageOptionsProviderMock.Setup(x => x.GetOptions()).ReturnsAsync(importOptions); var textImportService = new TextImportService(); - var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, textImportService); - await importManager.ImportTextAsync(fileContent); - var cuesheet = new Cuesheet - { - Artist = "Testartist", - Title = "Testtitle" - }; + var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, textImportService, traceChangeManager); // Act - cuesheet.Import(sessionStateContainer.ImportCuesheet!, testHelper.ApplicationOptions); + await importManager.ImportTextAsync(fileContent); // Assert Assert.IsNull(sessionStateContainer.Importfile?.AnalyseException); Assert.IsNotNull(sessionStateContainer.ImportCuesheet); - Assert.IsNull(cuesheet.Artist); - Assert.IsNull(cuesheet.Title); - Assert.AreEqual(8, cuesheet.Tracks.Count); - Assert.AreEqual(new TimeSpan(1, 15, 54), cuesheet.Tracks.Last().End); + Assert.IsNull(sessionStateContainer.ImportCuesheet.Artist); + Assert.IsNull(sessionStateContainer.ImportCuesheet.Title); + Assert.AreEqual(8, sessionStateContainer.ImportCuesheet.Tracks.Count); + Assert.AreEqual(new TimeSpan(1, 15, 54), sessionStateContainer.ImportCuesheet.Tracks.Last().End); } [TestMethod()] diff --git a/AudioCuesheetEditorTests/Model/UI/TraceChangeManagerTests.cs b/AudioCuesheetEditorTests/Model/UI/TraceChangeManagerTests.cs index 9128b69d..5c79cf59 100644 --- a/AudioCuesheetEditorTests/Model/UI/TraceChangeManagerTests.cs +++ b/AudioCuesheetEditorTests/Model/UI/TraceChangeManagerTests.cs @@ -13,6 +13,9 @@ using AudioCuesheetEditor.Model.Entity; using AudioCuesheetEditor.Model.Options; using AudioCuesheetEditor.Services.IO; +using AudioCuesheetEditor.Extensions; +using AudioCuesheetEditor.Data.Options; +using Moq; namespace AudioCuesheetEditor.Model.UI.Tests { @@ -150,10 +153,12 @@ public void TrackListTest() } [TestMethod()] - public void ImportCuesheetTest() + public async Task Import_ValidTextfile_IsUndoable() { + // Arrange var testhelper = new TestHelper(); - var manager = new TraceChangeManager(TestHelper.CreateLogger()); + var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger()); + var sessionStateContainer = new SessionStateContainer(traceChangeManager); var textImportMemoryStream = new MemoryStream(Resources.Textimport_with_Cuesheetdata); using var reader = new StreamReader(textImportMemoryStream); List lines = []; @@ -162,44 +167,109 @@ public void ImportCuesheetTest() lines.Add(reader.ReadLine()); } var fileContent = lines.AsReadOnly(); - var importService = new TextImportService(); - var importOptions = new ImportOptions + var localStorageOptionsProviderMock = new Mock(); + var importOptions = new ImportOptions(); + importOptions.TextImportScheme.SchemeCuesheet = "(?'Artist'\\A.*) - (?'Title'[a-zA-Z0-9_ .();äöü&:,]{1,}) - (?'Cataloguenumber'.{1,})"; + importOptions.TextImportScheme.SchemeTracks = TextImportScheme.DefaultSchemeTracks; + localStorageOptionsProviderMock.Setup(x => x.GetOptions()).ReturnsAsync(importOptions); + var textImportService = new TextImportService(); + var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, textImportService, traceChangeManager); + Boolean eventFired = false; + sessionStateContainer.Cuesheet.TrackAdded += delegate { - TextImportScheme = new TextImportScheme() - { - SchemeCuesheet = "(?'Artist'\\A.*) - (?'Title'[a-zA-Z0-9_ .();äöü&:,]{1,}) - (?'Cataloguenumber'.{1,})", - SchemeTracks = TextImportScheme.DefaultSchemeTracks - } + eventFired = true; }; - var importfile = importService.Analyse(importOptions, fileContent); - var cuesheet = new Cuesheet(); + // Act + await importManager.ImportTextAsync(fileContent); + // Assert + Assert.IsTrue(traceChangeManager.CanUndo); + Assert.IsFalse(traceChangeManager.CanRedo); + Assert.IsNotNull(sessionStateContainer.ImportCuesheet); + Assert.AreEqual("DJFreezeT", sessionStateContainer.ImportCuesheet.Artist); + Assert.AreEqual("0123456789123", sessionStateContainer.ImportCuesheet.Cataloguenumber.Value); + Assert.AreNotEqual(0, sessionStateContainer.ImportCuesheet.Tracks.Count); + Assert.IsTrue(traceChangeManager.CanUndo); + Assert.IsFalse(eventFired); + } + + [TestMethod()] + public async Task UndoImport_ValidTextfile_ResetsToEmptyCuesheet() + { + // Arrange + var testhelper = new TestHelper(); + var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger()); + var sessionStateContainer = new SessionStateContainer(traceChangeManager); + var textImportMemoryStream = new MemoryStream(Resources.Textimport_with_Cuesheetdata); + using var reader = new StreamReader(textImportMemoryStream); + List lines = []; + while (reader.EndOfStream == false) + { + lines.Add(reader.ReadLine()); + } + var fileContent = lines.AsReadOnly(); + var localStorageOptionsProviderMock = new Mock(); + var importOptions = new ImportOptions(); + importOptions.TextImportScheme.SchemeCuesheet = "(?'Artist'\\A.*) - (?'Title'[a-zA-Z0-9_ .();äöü&:,]{1,}) - (?'Cataloguenumber'.{1,})"; + importOptions.TextImportScheme.SchemeTracks = TextImportScheme.DefaultSchemeTracks; + localStorageOptionsProviderMock.Setup(x => x.GetOptions()).ReturnsAsync(importOptions); + var textImportService = new TextImportService(); + var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, textImportService, traceChangeManager); Boolean eventFired = false; - cuesheet.TrackAdded += delegate + sessionStateContainer.Cuesheet.TrackAdded += delegate { eventFired = true; }; - manager.TraceChanges(cuesheet); - Assert.IsFalse(manager.CanUndo); - Assert.IsFalse(manager.CanRedo); - Assert.IsNotNull(importfile.AnalysedCuesheet); - cuesheet.Import(importfile.AnalysedCuesheet, testhelper.ApplicationOptions, manager); - Assert.AreEqual("DJFreezeT", cuesheet.Artist); - Assert.AreEqual("0123456789123", cuesheet.Cataloguenumber.Value); - Assert.AreNotEqual(0, cuesheet.Tracks.Count); - Assert.IsTrue(manager.CanUndo); - manager.Undo(); - Assert.AreEqual(0, cuesheet.Tracks.Count); - Assert.IsTrue(String.IsNullOrEmpty(cuesheet.Artist)); - Assert.IsTrue(String.IsNullOrEmpty(cuesheet.Cataloguenumber.Value)); - Assert.IsFalse(manager.CanUndo); - Assert.IsTrue(manager.CanRedo); - manager.Redo(); - Assert.AreEqual("DJFreezeT", cuesheet.Artist); - Assert.AreEqual("0123456789123", cuesheet.Cataloguenumber.Value); - Assert.AreNotEqual(0, cuesheet.Tracks.Count); + await importManager.ImportTextAsync(fileContent); + // Act + traceChangeManager.Undo(); + // Assert + Assert.AreEqual(0, sessionStateContainer.ImportCuesheet?.Tracks.Count); + Assert.IsTrue(String.IsNullOrEmpty(sessionStateContainer.ImportCuesheet?.Artist)); + Assert.IsTrue(String.IsNullOrEmpty(sessionStateContainer.ImportCuesheet?.Cataloguenumber.Value)); + Assert.IsFalse(traceChangeManager.CanUndo); + Assert.IsTrue(traceChangeManager.CanRedo); Assert.IsFalse(eventFired); } + [TestMethod()] + public async Task UndoAndRedoImport_ValidTextfile_ResetsTextfileValues() + { + // Arrange + var testhelper = new TestHelper(); + var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger()); + var sessionStateContainer = new SessionStateContainer(traceChangeManager); + var textImportMemoryStream = new MemoryStream(Resources.Textimport_with_Cuesheetdata); + using var reader = new StreamReader(textImportMemoryStream); + List lines = []; + while (reader.EndOfStream == false) + { + lines.Add(reader.ReadLine()); + } + var fileContent = lines.AsReadOnly(); + var localStorageOptionsProviderMock = new Mock(); + var importOptions = new ImportOptions(); + importOptions.TextImportScheme.SchemeCuesheet = "(?'Artist'\\A.*) - (?'Title'[a-zA-Z0-9_ .();äöü&:,]{1,}) - (?'Cataloguenumber'.{1,})"; + importOptions.TextImportScheme.SchemeTracks = TextImportScheme.DefaultSchemeTracks; + localStorageOptionsProviderMock.Setup(x => x.GetOptions()).ReturnsAsync(importOptions); + var textImportService = new TextImportService(); + var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, textImportService, traceChangeManager); + Boolean eventFired = false; + sessionStateContainer.Cuesheet.TrackAdded += delegate + { + eventFired = true; + }; + await importManager.ImportTextAsync(fileContent); + traceChangeManager.Undo(); + // Act + traceChangeManager.Redo(); + // Assert + Assert.AreEqual("DJFreezeT", sessionStateContainer.ImportCuesheet?.Artist); + Assert.AreEqual("0123456789123", sessionStateContainer.ImportCuesheet?.Cataloguenumber.Value); + Assert.AreEqual(39, sessionStateContainer.ImportCuesheet?.Tracks.Count); + Assert.IsFalse(eventFired); + + } + [TestMethod()] public void RemoveTracksTest() {