From 9d707cb850b5d5303c90ee62370f4ccd43f876a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Wagenf=C3=BChr?= Date: Thu, 11 Nov 2021 20:49:59 +0100 Subject: [PATCH] fix: also detect renamed files (#38) This is needed because some Software, i.e. Chrome, downloads a file to the desired directory with a name like "XXX.csv.crdownload" and renames it to "XXX.csv" after the download was finished. The service did not detect such actions before Closes #33 --- .../CsvFileWatcherBackgroundServiceTests.cs | 39 +++++++++++++++++++ .../CsvFileWatcherBackgroundService.cs | 19 ++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/CsvProc9000.Tests/BackgroundServices/CsvFileWatcherBackgroundServiceTests.cs b/src/CsvProc9000.Tests/BackgroundServices/CsvFileWatcherBackgroundServiceTests.cs index d1d981c..1d12100 100644 --- a/src/CsvProc9000.Tests/BackgroundServices/CsvFileWatcherBackgroundServiceTests.cs +++ b/src/CsvProc9000.Tests/BackgroundServices/CsvFileWatcherBackgroundServiceTests.cs @@ -79,6 +79,7 @@ public void Dispose_Disposes_FileSystemWatcher() sut.Dispose(); fileSystemWatcher.VerifyRemove(watcher => watcher.Created -= It.IsAny()); + fileSystemWatcher.VerifyRemove(watcher => watcher.Renamed -= It.IsAny()); } [Fact] @@ -119,6 +120,44 @@ public void Add_Created_Files_To_Pool() job.TargetFile == fileInfoMock.Object)), Times.Once); } + [Fact] + public void Not_Add_Renamed_Files_To_Pool_When_Wrong_Change_Type() + { + var (context, fileSystemWatcher) = CreateContext(); + _ = context.Build(); + + fileSystemWatcher + .Raise(watcher => watcher.Renamed += null, + new RenamedEventArgs(WatcherChangeTypes.Deleted, "something", "some name", "some old name")); + + context + .For() + .Verify(pool => pool.Add(It.IsAny()), Times.Never); + } + + [Fact] + public void Add_Renamed_Files_To_Pool() + { + var (context, fileSystemWatcher) = CreateContext(); + _ = context.Build(); + + var fileInfoMock = new Mock(); + + context + .For() + .Setup(fileSystem => fileSystem.FileInfo.FromFileName(It.IsAny())) + .Returns(fileInfoMock.Object); + + fileSystemWatcher + .Raise(watcher => watcher.Renamed += null, + new RenamedEventArgs(WatcherChangeTypes.All, "something", "some file", "some old name")); + + context + .For() + .Verify(pool => pool.Add(It.Is(job => + job.TargetFile == fileInfoMock.Object)), Times.Once); + } + private static (ArrangeContext, Mock) CreateContext() { var options = new CsvProcessorOptions(); diff --git a/src/CsvProc9000/BackgroundServices/CsvFileWatcherBackgroundService.cs b/src/CsvProc9000/BackgroundServices/CsvFileWatcherBackgroundService.cs index 7d2f5b0..99a8230 100644 --- a/src/CsvProc9000/BackgroundServices/CsvFileWatcherBackgroundService.cs +++ b/src/CsvProc9000/BackgroundServices/CsvFileWatcherBackgroundService.cs @@ -36,6 +36,7 @@ public CsvFileWatcherBackgroundService( _fileSystemWatcher.Filter = "*.csv"; _fileSystemWatcher.Created += OnFileCreated; + _fileSystemWatcher.Renamed += OnFileRenamed; } protected override Task ExecuteAsync(CancellationToken stoppingToken) @@ -60,6 +61,7 @@ public override void Dispose() base.Dispose(); _fileSystemWatcher.Created -= OnFileCreated; + _fileSystemWatcher.Renamed -= OnFileRenamed; _fileSystemWatcher.Dispose(); } @@ -68,11 +70,24 @@ private void OnFileCreated(object sender, FileSystemEventArgs eventArgs) if (!eventArgs.ChangeType.HasFlag(WatcherChangeTypes.Created)) return; _logger.LogDebug("FileWatcher: File Created: {File}", eventArgs.FullPath); + AddJobForFile(eventArgs.FullPath); + } - var file = _fileSystem.FileInfo.FromFileName(eventArgs.FullPath); + private void OnFileRenamed(object sender, RenamedEventArgs eventArgs) + { + if (!eventArgs.ChangeType.HasFlag(WatcherChangeTypes.Renamed)) return; + + _logger.LogDebug("FileWatcher: File Renamed: from {OldFile} to {File}", + eventArgs.OldFullPath, eventArgs.FullPath); + AddJobForFile(eventArgs.FullPath); + } + + private void AddJobForFile(string filePath) + { + var file = _fileSystem.FileInfo.FromFileName(filePath); var job = new CsvProcessJob(file); - _logger.LogDebug("FileWatcher: Added CsvProcessJob #{JobId}", job.Id); + _logger.LogDebug("FileWatcher: Added CsvProcessJob #{JobId} for {File}", job.Id, filePath); _jobPool.Add(job); }