diff --git a/src/Downloader.Test/Helper/DownloadServiceEventsState.cs b/src/Downloader.Test/Helper/DownloadServiceEventsState.cs index c23147c..024f103 100644 --- a/src/Downloader.Test/Helper/DownloadServiceEventsState.cs +++ b/src/Downloader.Test/Helper/DownloadServiceEventsState.cs @@ -9,22 +9,22 @@ public class DownloadServiceEventsState public bool DownloadSuccessfulCompleted { get; set; } public bool IsDownloadCancelled { get; set; } public bool DownloadProgressIsCorrect { get; set; } = true; - public int DownloadProgressCount { get; set; } = 0; + public int DownloadProgressCount { get; set; } public Exception DownloadError { get; set; } public DownloadServiceEventsState(IDownloadService downloadService) { - downloadService.DownloadStarted += (s, e) => { + downloadService.DownloadStarted += (_, e) => { DownloadStarted = true; ActualFileName = e.FileName; }; - downloadService.DownloadProgressChanged += (s, e) => { + downloadService.DownloadProgressChanged += (_, e) => { DownloadProgressCount++; - DownloadProgressIsCorrect &= e.ProgressPercentage == downloadService.Package.SaveProgress; + DownloadProgressIsCorrect &= Math.Abs(e.ProgressPercentage - downloadService.Package.SaveProgress) < 0.1; }; - downloadService.DownloadFileCompleted += (s, e) => { + downloadService.DownloadFileCompleted += (_, e) => { DownloadSuccessfulCompleted = e.Error == null && !e.Cancelled; DownloadError = e.Error; IsDownloadCancelled = DownloadSuccessfulCompleted == false && DownloadError == null; diff --git a/src/Downloader.Test/IntegrationTests/DownloadServiceTest.cs b/src/Downloader.Test/IntegrationTests/DownloadServiceTest.cs index b51f726..222974f 100644 --- a/src/Downloader.Test/IntegrationTests/DownloadServiceTest.cs +++ b/src/Downloader.Test/IntegrationTests/DownloadServiceTest.cs @@ -1,5 +1,7 @@ using Downloader.DummyHttpServer; +using Downloader.Extensions.Logging; using Downloader.Test.Helper; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.ComponentModel; @@ -22,14 +24,14 @@ public Task InitializeAsync() return Task.CompletedTask; } - public virtual Task DisposeAsync() + public new virtual async Task DisposeAsync() { Package?.Clear(); - Package?.Storage?.Dispose(); + if (Package?.Storage != null) + await Package.Storage.DisposeAsync(); + if (!string.IsNullOrWhiteSpace(Filename)) File.Delete(Filename); - - return Task.CompletedTask; } private DownloadConfiguration GetDefaultConfig() @@ -140,7 +142,7 @@ public async Task TestPackageSituationAfterDispose() await Package.Storage.FlushAsync(); // act - Dispose(); + await base.DisposeAsync(); // assert Assert.NotNull(Package.Chunks); @@ -158,15 +160,14 @@ public async Task TestPackageChunksDataAfterDispose() Package.TotalFileSize = chunkSize * 64; Package.BuildStorage(false, 1024 * 1024); new ChunkHub(Options).SetFileChunks(Package); - for (int i = 0; i < Package.Chunks.Length; i++) + foreach (Chunk chunk in Package.Chunks) { - var chunk = Package.Chunks[i]; await Package.Storage.WriteAsync(chunk.Start, dummyData, chunkSize); } // act await Package.FlushAsync(); - Dispose(); + await base.DisposeAsync(); var stream = Package.Storage.OpenRead(); // assert @@ -243,12 +244,10 @@ public async Task ResumePerformanceTest() public async Task PauseResumeTest() { // arrange - AsyncCompletedEventArgs eventArgs = null; var paused = false; var cancelled = false; string address = DummyFileHelper.GetFileUrl(DummyFileHelper.FileSize16Kb); Options = GetDefaultConfig(); - DownloadFileCompleted += (_, e) => eventArgs = e; // act DownloadProgressChanged += (_, _) => { @@ -351,6 +350,7 @@ public async Task ResumeNotSupportedUrlTest() { actualChunksCount = Package.Chunks.Length; } + maxProgressPercentage = Math.Max(e.ProgressPercentage, maxProgressPercentage); }; @@ -390,7 +390,7 @@ public async Task ActiveChunksTest() Assert.True(Package.IsSupportDownloadInRange); Assert.True(Package.IsSaveComplete); foreach (var activeChunks in allActiveChunksCount) - Assert.True(activeChunks >= 1 && activeChunks <= 4); + Assert.True(activeChunks is >= 1 and <= 4); } [Fact] @@ -413,7 +413,7 @@ public async Task ActiveChunksWithRangeNotSupportedUrlTest() Assert.False(Package.IsSupportDownloadInRange); Assert.True(Package.IsSaveComplete); foreach (var activeChunks in allActiveChunksCount) - Assert.True(activeChunks >= 1 && activeChunks <= 4); + Assert.True(activeChunks is >= 1 and <= 4); } [Fact] @@ -452,7 +452,7 @@ public async Task ActiveChunksAfterCancelResumeWithNotSupportedUrlTest() Assert.Equal(1, Options.ParallelCount); Assert.Equal(1, Options.ChunkCount); foreach (var activeChunks in allActiveChunksCount) - Assert.True(activeChunks >= 1 && activeChunks <= 4); + Assert.True(activeChunks is >= 1 and <= 4); } [Fact] @@ -480,8 +480,8 @@ public async Task TestPackageDataAfterCompletionWithSuccess() public async Task TestPackageStatusAfterCompletionWithSuccess() { // arrange - var url = DummyFileHelper.GetFileWithNameUrl(DummyFileHelper.SampleFile16KbName, DummyFileHelper.FileSize16Kb); - var noneStatus = Package.Status; + var url = DummyFileHelper.GetFileWithNameUrl(DummyFileHelper.SampleFile16KbName, + DummyFileHelper.FileSize16Kb); var createdStatus = DownloadStatus.None; var runningStatus = DownloadStatus.None; var pausedStatus = DownloadStatus.None; @@ -491,7 +491,7 @@ public async Task TestPackageStatusAfterCompletionWithSuccess() DownloadStarted += (_, _) => createdStatus = Package.Status; DownloadProgressChanged += (_, e) => { runningStatus = Package.Status; - if (e.ProgressPercentage > 50 && e.ProgressPercentage < 70) + if (e.ProgressPercentage is > 50 and < 70) { Pause(); pausedStatus = Package.Status; @@ -529,8 +529,8 @@ public async Task TestSerializePackageAfterCancel(bool onMemory) ChunkDownloadProgressChanged += (_, _) => CancelAsync(); DownloadFileCompleted += (_, e) => { package = e.UserState as DownloadPackage; - if (package!.Status != DownloadStatus.Completed) - packageText = System.Text.Json.JsonSerializer.Serialize(package!); + if (package?.Status != DownloadStatus.Completed) + packageText = System.Text.Json.JsonSerializer.Serialize(package); }; // act @@ -570,8 +570,8 @@ public async Task TestResumeFromSerializedPackage(bool onMemory) }; DownloadFileCompleted += (_, e) => { package = e.UserState as DownloadPackage; - if (package!.Status != DownloadStatus.Completed) - packageText = System.Text.Json.JsonSerializer.Serialize(package!); + if (package?.Status != DownloadStatus.Completed) + packageText = System.Text.Json.JsonSerializer.Serialize(package); }; // act @@ -601,7 +601,6 @@ public async Task TestPackageStatusAfterCancellation() { // arrange var url = DummyFileHelper.GetFileWithNameUrl(DummyFileHelper.SampleFile16KbName, DummyFileHelper.FileSize16Kb); - var noneStatus = Package.Status; var createdStatus = DownloadStatus.None; var runningStatus = DownloadStatus.None; var cancelledStatus = DownloadStatus.None; @@ -610,7 +609,7 @@ public async Task TestPackageStatusAfterCancellation() DownloadStarted += (_, _) => createdStatus = Package.Status; DownloadProgressChanged += async (_, e) => { runningStatus = Package.Status; - if (e.ProgressPercentage > 50 && e.ProgressPercentage < 70) + if (e.ProgressPercentage is > 50 and < 70) { await CancelTaskAsync(); cancelledStatus = Package.Status; @@ -635,12 +634,11 @@ public async Task TestPackageStatusAfterCancellation() public async Task TestResumeDownloadImmediatelyAfterCancellationAsync() { // arrange - var completedState = DownloadStatus.None; var checkProgress = false; var secondStartProgressPercent = -1d; var url = DummyFileHelper.GetFileWithNameUrl(DummyFileHelper.SampleFile16KbName, DummyFileHelper.FileSize16Kb); var tcs = new TaskCompletionSource(); - DownloadFileCompleted += (_, _) => completedState = Package.Status; + DownloadFileCompleted += (_, _) => _ = Package.Status; // act DownloadProgressChanged += async (_, e) => { @@ -651,7 +649,7 @@ public async Task TestResumeDownloadImmediatelyAfterCancellationAsync() checkProgress = false; secondStartProgressPercent = e.ProgressPercentage; } - else if (e.ProgressPercentage > 50 && e.ProgressPercentage < 60) + else if (e.ProgressPercentage is > 50 and < 60) { await CancelTaskAsync(); checkProgress = true; @@ -680,7 +678,7 @@ public async Task TestStopDownloadOnClearWhenRunning() // act DownloadProgressChanged += async (_, e) => { - if (e.ProgressPercentage > 50 && e.ProgressPercentage < 60) + if (e.ProgressPercentage is > 50 and < 60) await Clear(); }; await DownloadFileTaskAsync(url); @@ -723,7 +721,6 @@ public async Task TestMinimumSizeOfChunking() // arrange Options = GetDefaultConfig(); Options.MinimumSizeOfChunking = DummyFileHelper.FileSize16Kb; - var states = new DownloadServiceEventsState(this); var url = DummyFileHelper.GetFileWithNameUrl(DummyFileHelper.SampleFile16KbName, DummyFileHelper.FileSize16Kb); var activeChunks = 0; int? chunkCounts = null; @@ -760,5 +757,18 @@ public async Task TestCreatePathIfNotExist() Assert.True(Package.IsSaveComplete); Assert.StartsWith(dir.FullName, Package.FileName); Assert.True(File.Exists(Package.FileName), "FileName: " + Package.FileName); - } + } + + [Fact] + public void TestAddLogger() + { + // arrange + var logFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + + // act + AddLogger(FileLogger.Factory(logFile)); + + // assert + Assert.NotNull(Logger); + } } \ No newline at end of file diff --git a/src/Downloader.Test/UnitTests/DownloadConfigurationTest.cs b/src/Downloader.Test/UnitTests/DownloadConfigurationTest.cs index 8986907..d6f7af3 100644 --- a/src/Downloader.Test/UnitTests/DownloadConfigurationTest.cs +++ b/src/Downloader.Test/UnitTests/DownloadConfigurationTest.cs @@ -57,6 +57,11 @@ public void CloneTest() CheckDiskSizeBeforeDownload = false, MinimumSizeOfChunking = 1024, ClearPackageOnCompletionWithFailure = true, + ReserveStorageSpaceBeforeStartingDownload = true, + EnableLiveStreaming = true, + RangeDownload = true, + RangeHigh = 102400, + RangeLow = 10240 }; // act diff --git a/src/Downloader/ISizeableObject.cs b/src/Downloader/ISizeableObject.cs index 48860b8..d5476df 100644 --- a/src/Downloader/ISizeableObject.cs +++ b/src/Downloader/ISizeableObject.cs @@ -2,5 +2,5 @@ internal interface ISizeableObject { - public int Length { get; set; } + public int Length { get; } } \ No newline at end of file diff --git a/src/Downloader/Packet.cs b/src/Downloader/Packet.cs index 945a425..a66b43e 100644 --- a/src/Downloader/Packet.cs +++ b/src/Downloader/Packet.cs @@ -5,7 +5,7 @@ namespace Downloader; internal class Packet(long position, byte[] data, int len) : IDisposable, ISizeableObject { public Memory Data { get; set; } = data.AsMemory(0, len); - public int Length { get; set; } = len; + public int Length { get; } = len; public long Position { get; set; } = position; public long EndOffset => Position + Length; diff --git a/src/Downloader/Request.cs b/src/Downloader/Request.cs index 7aabef2..19387d3 100644 --- a/src/Downloader/Request.cs +++ b/src/Downloader/Request.cs @@ -33,7 +33,8 @@ public class Request /// /// The URL address to create the request for. public Request(string address) : this(address, new RequestConfiguration()) - { } + { + } /// /// Initializes a new instance of the class with the specified address and configuration. @@ -50,7 +51,8 @@ public Request(string address, RequestConfiguration config) Address = uri; _configuration = config ?? new RequestConfiguration(); _responseHeaders = new Dictionary(); - _contentRangePattern = new Regex(@"bytes\s*((?\d*)\s*-\s*(?\d*)|\*)\s*\/\s*(?\d+|\*)", RegexOptions.Compiled); + _contentRangePattern = new Regex(@"bytes\s*((?\d*)\s*-\s*(?\d*)|\*)\s*\/\s*(?\d+|\*)", + RegexOptions.Compiled); } /// @@ -94,6 +96,7 @@ private HttpWebRequest GetRequest(string method) { request.Credentials = _configuration.Credentials; } + if (_configuration.IfModifiedSince.HasValue) { request.IfModifiedSince = _configuration.IfModifiedSince.Value; @@ -142,12 +145,14 @@ private async Task FetchResponseHeaders(bool addRange = true) } } catch (WebException exp) when (_configuration.AllowAutoRedirect && - exp.Response is HttpWebResponse response && - response.SupportsHeaders && - (response.StatusCode == HttpStatusCode.Found || - response.StatusCode == HttpStatusCode.Moved || - response.StatusCode == HttpStatusCode.MovedPermanently || - response.StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable)) + exp.Response is HttpWebResponse { + SupportsHeaders: true, + StatusCode: + HttpStatusCode.Found or + HttpStatusCode.Moved or + HttpStatusCode.MovedPermanently or + HttpStatusCode.RequestedRangeNotSatisfiable + } response) { if (response.StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable) { @@ -222,7 +227,8 @@ public async Task ThrowIfIsNotSupportDownloadInRange() var isSupport = await IsSupportDownloadInRange().ConfigureAwait(false); if (isSupport == false) { - throw new NotSupportedException("The downloader cannot continue downloading because the network or server failed to download in range."); + throw new NotSupportedException( + "The downloader cannot continue downloading because the network or server failed to download in range."); } }