diff --git a/src/Networking/NexusMods.Networking.Downloaders/DownloadService.cs b/src/Networking/NexusMods.Networking.Downloaders/DownloadService.cs
index 7d8f75c9cf..52d413dbb8 100644
--- a/src/Networking/NexusMods.Networking.Downloaders/DownloadService.cs
+++ b/src/Networking/NexusMods.Networking.Downloaders/DownloadService.cs
@@ -1,8 +1,8 @@
using System.Collections.ObjectModel;
+using System.ComponentModel;
using DynamicData;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
-using NexusMods.Abstractions.MnemonicDB.Attributes.Extensions;
using NexusMods.Abstractions.NexusWebApi.Types;
using NexusMods.MnemonicDB.Abstractions;
using NexusMods.Networking.Downloaders.Interfaces;
@@ -14,8 +14,7 @@
using Microsoft.Extensions.Hosting;
using NexusMods.Abstractions.Activities;
using NexusMods.Abstractions.IO;
-using NexusMods.MnemonicDB.Abstractions.DatomIterators;
-using NexusMods.MnemonicDB.Abstractions.Query;
+using NexusMods.Abstractions.Settings;
using NexusMods.Paths;
namespace NexusMods.Networking.Downloaders;
@@ -25,6 +24,9 @@ public class DownloadService : IDownloadService, IDisposable, IHostedService
{
///
public ReadOnlyObservableCollection Downloads => _downloadsCollection;
+
+ ///
+ public AbsolutePath OngoingDownloadsDirectory { get; private set; }
private ReadOnlyObservableCollection _downloadsCollection = ReadOnlyObservableCollection.Empty;
private readonly SourceCache _downloads = new(t => t.PersistentState.Id);
@@ -35,13 +37,24 @@ public class DownloadService : IDownloadService, IDisposable, IHostedService
private readonly CompositeDisposable _disposables;
private readonly IFileStore _fileStore;
- public DownloadService(ILogger logger, IServiceProvider provider, IFileStore fileStore, IConnection conn)
+ public DownloadService(
+ ILogger logger,
+ IServiceProvider provider,
+ IFileStore fileStore,
+ IConnection conn,
+ IFileSystem fs,
+ ISettingsManager settingsManager)
{
_logger = logger;
_provider = provider;
_conn = conn;
_disposables = new CompositeDisposable();
_fileStore = fileStore;
+ OngoingDownloadsDirectory = settingsManager.Get().OngoingDownloadLocation.ToPath(fs);
+ if (!OngoingDownloadsDirectory.DirectoryExists())
+ {
+ OngoingDownloadsDirectory.CreateDirectory();
+ }
}
internal IEnumerable GetItemsToResume()
@@ -206,11 +219,9 @@ public async Task StopAsync(CancellationToken cancellationToken)
{
var suspendingTasks = _downloads.Items
.Where(dl => dl.PersistentState.Status == DownloadTaskStatus.Downloading)
- // TODO(Al12rs): should Suspend() instead, but only after moving ongoing dl files outside Temp folder,
- // that is otherwise cleaned up on application close, causing exceptions due to file in use,
- // on top of discarding all the progress.
- .Select(dl => dl.Cancel());
+ .Select(dl => dl.Suspend());
await Task.WhenAll(suspendingTasks);
}
+
}
diff --git a/src/Networking/NexusMods.Networking.Downloaders/DownloadSettings.cs b/src/Networking/NexusMods.Networking.Downloaders/DownloadSettings.cs
new file mode 100644
index 0000000000..360dd80416
--- /dev/null
+++ b/src/Networking/NexusMods.Networking.Downloaders/DownloadSettings.cs
@@ -0,0 +1,67 @@
+using JetBrains.Annotations;
+using Microsoft.Extensions.DependencyInjection;
+using NexusMods.Abstractions.Settings;
+using NexusMods.Paths;
+
+namespace NexusMods.Networking.Downloaders;
+
+///
+/// Settings for downloads.
+///
+[PublicAPI]
+public record DownloadSettings : ISettings
+{
+
+ ///
+ /// Base directory where files generated during ongoing download operations are located.
+ ///
+ ///
+ /// Should not be placed in Temp or similar directories,
+ /// as download files may need to persist across application and system restarts.
+ ///
+ public ConfigurablePath OngoingDownloadLocation { get; set; }
+
+
+ ///
+ public static ISettingsBuilder Configure(ISettingsBuilder settingsBuilder)
+ {
+ return settingsBuilder
+ .ConfigureDefault(CreateDefault)
+ .ConfigureStorageBackend(builder => builder.UseJson());
+ }
+
+ ///
+ /// Create default value.
+ ///
+ public static DownloadSettings CreateDefault(IServiceProvider serviceProvider)
+ {
+ var os = serviceProvider.GetRequiredService().OS;
+
+ return new DownloadSettings
+ {
+ OngoingDownloadLocation = GetStandardDownloadPath(os),
+ };
+ }
+
+ private static ConfigurablePath GetStandardDownloadPath(IOSInformation os)
+ {
+ var basePath = os.MatchPlatform(
+ onWindows: () => KnownPath.LocalApplicationDataDirectory,
+ onLinux: () => KnownPath.XDG_DATA_HOME,
+ onOSX: () => KnownPath.LocalApplicationDataDirectory
+ );
+ // NOTE: OSX ".App" is apparently special, using _ instead of . to prevent weirdness
+ var baseDirectoryName = os.IsOSX ? "NexusMods_App/" : "NexusMods.App/";
+ var downloadsSubPath = baseDirectoryName + "Downloads/Ongoing";
+
+ return new ConfigurablePath(basePath, downloadsSubPath);
+ }
+
+ ///
+ /// Absolute path to the standard downloads' folder.
+ ///
+ public static AbsolutePath GetStandardDownloadsFolder(IFileSystem fs)
+ {
+ return GetStandardDownloadPath(fs.OS).ToPath(fs);
+ }
+}
diff --git a/src/Networking/NexusMods.Networking.Downloaders/Interfaces/IDownloadService.cs b/src/Networking/NexusMods.Networking.Downloaders/Interfaces/IDownloadService.cs
index 7349b21573..be6a6ae835 100644
--- a/src/Networking/NexusMods.Networking.Downloaders/Interfaces/IDownloadService.cs
+++ b/src/Networking/NexusMods.Networking.Downloaders/Interfaces/IDownloadService.cs
@@ -20,6 +20,11 @@ public interface IDownloadService
///
ReadOnlyObservableCollection Downloads { get; }
+ ///
+ /// The base directory for ongoing downloads
+ ///
+ AbsolutePath OngoingDownloadsDirectory { get; }
+
///
/// Adds a task that will download from a NXM link.
///
diff --git a/src/Networking/NexusMods.Networking.Downloaders/Interfaces/IDownloadTask.cs b/src/Networking/NexusMods.Networking.Downloaders/Interfaces/IDownloadTask.cs
index 3a48c19854..1e0eb352cc 100644
--- a/src/Networking/NexusMods.Networking.Downloaders/Interfaces/IDownloadTask.cs
+++ b/src/Networking/NexusMods.Networking.Downloaders/Interfaces/IDownloadTask.cs
@@ -16,9 +16,9 @@ public interface IDownloadTask
DownloaderState.ReadOnly PersistentState { get; }
///
- /// The download location of the task.
+ /// Path of the ongoing download file
///
- public AbsolutePath DownloadLocation { get; }
+ public AbsolutePath DownloadPath { get; }
///
/// Calculates the download speed of the current job.
@@ -93,12 +93,7 @@ public enum DownloadTaskStatus : byte
Downloading,
///
- /// The mod is being archived (and possibly installed) to a loadout.
- ///
- Installing,
-
- ///
- /// The task has ran to completion.
+ /// The task has run to completion.
///
Completed,
diff --git a/src/Networking/NexusMods.Networking.Downloaders/Services.cs b/src/Networking/NexusMods.Networking.Downloaders/Services.cs
index ba79dc2c5e..bad08dcc64 100644
--- a/src/Networking/NexusMods.Networking.Downloaders/Services.cs
+++ b/src/Networking/NexusMods.Networking.Downloaders/Services.cs
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
+using NexusMods.Abstractions.Settings;
using NexusMods.MnemonicDB.Abstractions;
using NexusMods.Networking.Downloaders.Interfaces;
using NexusMods.Networking.Downloaders.Tasks;
@@ -18,6 +19,7 @@ public static class Services
public static IServiceCollection AddDownloaders(this IServiceCollection services)
{
return services.AddSingleton()
+ .AddSettings()
.AddHostedService(sp=> sp.GetRequiredService())
.AddSingleton(sp=> sp.GetRequiredService())
.AddTransient()
diff --git a/src/Networking/NexusMods.Networking.Downloaders/Tasks/ADownloadTask.cs b/src/Networking/NexusMods.Networking.Downloaders/Tasks/ADownloadTask.cs
index e6dd8e0fdf..ba47ff2e1b 100644
--- a/src/Networking/NexusMods.Networking.Downloaders/Tasks/ADownloadTask.cs
+++ b/src/Networking/NexusMods.Networking.Downloaders/Tasks/ADownloadTask.cs
@@ -1,18 +1,13 @@
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-using DynamicData.Kernel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NexusMods.Abstractions.Activities;
using NexusMods.Abstractions.FileStore;
-using NexusMods.Abstractions.FileStore.Downloads;
using NexusMods.Abstractions.HttpDownloader;
-using NexusMods.Abstractions.IO;
-using NexusMods.DataModel;
using NexusMods.MnemonicDB.Abstractions;
using NexusMods.Networking.Downloaders.Interfaces;
using NexusMods.Networking.Downloaders.Tasks.State;
using NexusMods.Paths;
+using NexusMods.Paths.Utilities;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
@@ -30,33 +25,33 @@ public abstract class ADownloadTask : ReactiveObject, IDownloadTask
///
protected HttpDownloaderState? TransientState = null!;
protected ILogger Logger;
- protected TemporaryFileManager TemporaryFileManager;
protected HttpClient HttpClient;
protected IHttpDownloader HttpDownloader;
protected CancellationTokenSource CancellationTokenSource;
- protected TemporaryPath _downloadLocation = default!;
+ protected AbsolutePath _downloadPath = default!;
protected IFileSystem FileSystem;
protected IFileOriginRegistry FileOriginRegistry;
private DownloaderState.ReadOnly _persistentState;
-
+ private IDownloadService _downloadService;
+
protected ADownloadTask(IServiceProvider provider)
{
Connection = provider.GetRequiredService();
Logger = provider.GetRequiredService>();
- TemporaryFileManager = provider.GetRequiredService();
HttpClient = provider.GetRequiredService();
HttpDownloader = provider.GetRequiredService();
CancellationTokenSource = new CancellationTokenSource();
ActivityFactory = provider.GetRequiredService();
FileSystem = provider.GetRequiredService();
FileOriginRegistry = provider.GetRequiredService();
+ _downloadService = provider.GetRequiredService();
}
public void Init(DownloaderState.ReadOnly state)
{
PersistentState = state;
Downloaded = state.Downloaded;
- _downloadLocation = new TemporaryPath(FileSystem, FileSystem.FromUnsanitizedFullPath(state.DownloadPath), false);
+ _downloadPath = FileSystem.FromUnsanitizedFullPath(state.DownloadPath);
}
///
@@ -73,13 +68,19 @@ public void RefreshState()
///
protected EntityId Create(ITransaction tx)
{
- _downloadLocation = TemporaryFileManager.CreateFile();
+ // Add a subfolder for the download task
+ var guid = Guid.NewGuid().ToString();
+ var downloadSubfolder = _downloadService.OngoingDownloadsDirectory.Combine(guid);
+ downloadSubfolder.CreateDirectory();
+
+ _downloadPath = downloadSubfolder.Combine(guid).AppendExtension(KnownExtensions.Tmp);
+
var state = new DownloaderState.New(tx)
{
FriendlyName = "",
Status = DownloadTaskStatus.Idle,
Downloaded = Size.Zero,
- DownloadPath = DownloadLocation.ToString(),
+ DownloadPath = DownloadPath.ToString(),
};
return state.Id;
}
@@ -151,7 +152,7 @@ protected async Task MarkComplete()
[Reactive]
public DownloaderState.ReadOnly PersistentState { get; protected set; }
- public AbsolutePath DownloadLocation => _downloadLocation;
+ public AbsolutePath DownloadPath => _downloadPath;
[Reactive] public Bandwidth Bandwidth { get; set; } = Bandwidth.From(0);
@@ -173,6 +174,10 @@ public async Task Cancel()
try { await CancellationTokenSource.CancelAsync(); }
catch (Exception) { /* ignored */ }
await SetStatus(DownloadTaskStatus.Cancelled);
+
+ // Cleanup the download directory (this could actually still be in use by the downloader,
+ // since CancelAsync is not guaranteed to wait for exception handlers to finish handling the cancellation)
+ CleanupDownloadFiles();
}
///
@@ -193,24 +198,39 @@ public async Task Resume()
await SetStatus(DownloadTaskStatus.Downloading);
TransientState = new HttpDownloaderState
{
- Activity = ActivityFactory.Create(IHttpDownloader.Group, "Downloading {FileName}", DownloadLocation),
+ Activity = ActivityFactory.Create(IHttpDownloader.Group, "Downloading {FileName}", DownloadPath),
};
_ = StartActivityUpdater();
Logger.LogDebug("Dispatching download task for {Name}", PersistentState.FriendlyName);
- await Download(DownloadLocation, CancellationTokenSource.Token);
+ try
+ {
+ await Download(DownloadPath, CancellationTokenSource.Token);
+ }
+ catch (OperationCanceledException e)
+ {
+ return;
+ }
+
UpdateActivity();
await SetStatus(DownloadTaskStatus.Analyzing);
Logger.LogInformation("Finished download of {Name} starting analysis", PersistentState.FriendlyName);
await AnalyzeFile();
await MarkComplete();
+ CleanupDownloadFiles();
+ }
+
+ // Delete the download task subfolder and all files within it.
+ private void CleanupDownloadFiles()
+ {
+ DownloadPath.Parent.DeleteDirectory(recursive: true);
}
private async Task AnalyzeFile()
{
try
{
- await FileOriginRegistry.RegisterDownload(DownloadLocation, PersistentState.Id, PersistentState.FriendlyName);
+ await FileOriginRegistry.RegisterDownload(DownloadPath, PersistentState.Id, PersistentState.FriendlyName);
}
catch (Exception ex)
{
diff --git a/src/Networking/NexusMods.Networking.HttpDownloader/AdvancedHttpDownloader.cs b/src/Networking/NexusMods.Networking.HttpDownloader/AdvancedHttpDownloader.cs
index bd7c6a3f1a..2e2ccc6dc9 100644
--- a/src/Networking/NexusMods.Networking.HttpDownloader/AdvancedHttpDownloader.cs
+++ b/src/Networking/NexusMods.Networking.HttpDownloader/AdvancedHttpDownloader.cs
@@ -163,12 +163,12 @@ private async Task DownloadWithoutResume(IReadOnlyList
private static async Task FinalizeDownload(DownloadState state, CancellationToken cancel)
{
- var tempPath = state.TempFilePath;
+ var progressPath = state.ProgressFilePath;
if (state.HasIncompleteChunk) return Hash.Zero;
state.StateFilePath.Delete();
- File.Move(tempPath.ToString(), state.Destination.ToString(), true);
+ File.Move(progressPath.ToString(), state.Destination.ToString(), true);
return await state.Destination.XxHash64Async(token: cancel);
}
@@ -177,8 +177,8 @@ private static async Task FinalizeDownload(DownloadState state, Cancellati
private async Task FileWriterTask(DownloadState state, ChannelReader writes,
IActivitySource job, CancellationToken cancel)
{
- var tempPath = state.TempFilePath;
- await using var file = tempPath.Open(FileMode.OpenOrCreate, FileAccess.Write);
+ var progressPath = state.ProgressFilePath;
+ await using var file = progressPath.Open(FileMode.OpenOrCreate, FileAccess.Write);
file.SetLength((long)(ulong)state.TotalSize);
while (true)
@@ -471,7 +471,7 @@ private async Task InitiateState(AbsolutePath destination, Size s
{
DownloadState? state = null;
var stateFilePath = DownloadState.GetStateFilePath(destination);
- if (stateFilePath.FileExists && DownloadState.GetTempFilePath(destination).FileExists)
+ if (stateFilePath.FileExists && DownloadState.GetProgressFilePath(destination).FileExists)
{
_logger.LogInformation("Resuming prior download {FilePath}", destination);
state = await DeserializeDownloadState(stateFilePath, cancel);
diff --git a/src/Networking/NexusMods.Networking.HttpDownloader/DTOs/DownloadState.cs b/src/Networking/NexusMods.Networking.HttpDownloader/DTOs/DownloadState.cs
index b07bacb61c..ea00781f80 100644
--- a/src/Networking/NexusMods.Networking.HttpDownloader/DTOs/DownloadState.cs
+++ b/src/Networking/NexusMods.Networking.HttpDownloader/DTOs/DownloadState.cs
@@ -69,7 +69,7 @@ public Size CompletedSize
/// The file where the download is stored while it is in progress
///
[JsonIgnore]
- public AbsolutePath TempFilePath => GetTempFilePath(Destination);
+ public AbsolutePath ProgressFilePath => GetProgressFilePath(Destination);
///
/// Based on the destination, get the path to the state file
@@ -83,7 +83,7 @@ public Size CompletedSize
///
///
///
- public static AbsolutePath GetTempFilePath(AbsolutePath destination) => destination.ReplaceExtension(new Extension(".downloading"));
+ public static AbsolutePath GetProgressFilePath(AbsolutePath destination) => destination.ReplaceExtension(new Extension(".downloading"));
///
diff --git a/src/NexusMods.App.UI/Controls/DownloadGrid/Columns/DownloadStatus/DownloadStatusDesignViewModel.cs b/src/NexusMods.App.UI/Controls/DownloadGrid/Columns/DownloadStatus/DownloadStatusDesignViewModel.cs
index 6d73af8c31..15c86378b8 100644
--- a/src/NexusMods.App.UI/Controls/DownloadGrid/Columns/DownloadStatus/DownloadStatusDesignViewModel.cs
+++ b/src/NexusMods.App.UI/Controls/DownloadGrid/Columns/DownloadStatus/DownloadStatusDesignViewModel.cs
@@ -71,7 +71,6 @@ public static string FormatStatus(DownloadTaskStatus state, long totalBytes, lon
DownloadTaskStatus.Idle => Language.DownloadStatusDesignViewModel_FormatStatus_Queued,
DownloadTaskStatus.Paused => Language.DownloadStatusDesignViewModel_FormatStatus_Paused,
DownloadTaskStatus.Downloading => Language.DownloadStatusDesignViewModel_FormatStatus_Downloading,
- DownloadTaskStatus.Installing => Language.DownloadStatusDesignViewModel_FormatStatus_Installing,
DownloadTaskStatus.Completed => Language.DownloadStatusDesignViewModel_FormatStatus_Complete,
DownloadTaskStatus.Analyzing => Language.DownloadStatusDesignViewModel_FormatStatus_Analyzing,
DownloadTaskStatus.Cancelled => Language.DownloadStatusDesignViewModel_FormatStatus_Cancelled,
diff --git a/tests/Networking/NexusMods.Networking.Downloaders.Tests/DownloadServiceDataStoreTests.cs b/tests/Networking/NexusMods.Networking.Downloaders.Tests/DownloadServiceDataStoreTests.cs
index 18dec52295..dfda51ff2b 100644
--- a/tests/Networking/NexusMods.Networking.Downloaders.Tests/DownloadServiceDataStoreTests.cs
+++ b/tests/Networking/NexusMods.Networking.Downloaders.Tests/DownloadServiceDataStoreTests.cs
@@ -1,20 +1,22 @@
using FluentAssertions;
-using NexusMods.Abstractions.HttpDownloader;
using NexusMods.Games.RedEngine;
using NexusMods.Games.TestFramework;
using NexusMods.Networking.Downloaders.Interfaces;
-using NexusMods.Paths;
namespace NexusMods.Networking.Downloaders.Tests;
-public class DownloadServiceDataStoreTests(
- DownloadService downloadService,
- IServiceProvider serviceProvider,
- LocalHttpServer server,
- TemporaryFileManager temporaryFileManager,
- IHttpDownloader httpDownloader)
- : AGameTest(serviceProvider)
+public class DownloadServiceDataStoreTests : AGameTest
{
+ private readonly DownloadService _downloadService;
+ private readonly LocalHttpServer _server;
+
+ public DownloadServiceDataStoreTests(DownloadService downloadService,
+ IServiceProvider serviceProvider,
+ LocalHttpServer server) : base(serviceProvider)
+ {
+ _downloadService = downloadService;
+ _server = server;
+ }
// Create a new instance of the DownloadService
@@ -22,7 +24,7 @@ public class DownloadServiceDataStoreTests(
public async Task WhenComplete_StaysPersistedInDataStore()
{
var currentCount = GetTaskCountIncludingCompleted();
- await downloadService.AddTask(new Uri($"{server.Prefix}Resources/RootedAtGameFolder/-Skyrim 202X 9.0 - Architecture-2347-9-0-1664994366.zip"));
+ await _downloadService.AddTask(new Uri($"{_server.Prefix}Resources/RootedAtGameFolder/-Skyrim 202X 9.0 - Architecture-2347-9-0-1664994366.zip"));
var newCount = GetTaskCountIncludingCompleted();
newCount.Should().Be(currentCount + 1);
}
@@ -34,8 +36,8 @@ public async Task WhenStarted_IsPersistedInDataStore()
// Should be persisted into datastore on start, because
var currentCount = GetTasks().Count();
- var url = new Uri($"{server.Prefix}Resources/RootedAtGameFolder/-Skyrim 202X 9.0 - Architecture-2347-9-0-1664994366.zip");
- await downloadService.AddTask(url);
+ var url = new Uri($"{_server.Prefix}Resources/RootedAtGameFolder/-Skyrim 202X 9.0 - Architecture-2347-9-0-1664994366.zip");
+ await _downloadService.AddTask(url);
var newCount = GetTasks().Count();
newCount.Should().Be(currentCount + 1);
@@ -43,13 +45,13 @@ public async Task WhenStarted_IsPersistedInDataStore()
private IEnumerable GetTasks()
{
- return downloadService.Downloads
+ return _downloadService.Downloads
.ToList();
}
private int GetTaskCountIncludingCompleted()
{
- return downloadService.Downloads.Count;
+ return _downloadService.Downloads.Count;
}
}
diff --git a/tests/Networking/NexusMods.Networking.Downloaders.Tests/DownloadServiceTests.cs b/tests/Networking/NexusMods.Networking.Downloaders.Tests/DownloadServiceTests.cs
index 1c23ae71f7..999cd2ab65 100644
--- a/tests/Networking/NexusMods.Networking.Downloaders.Tests/DownloadServiceTests.cs
+++ b/tests/Networking/NexusMods.Networking.Downloaders.Tests/DownloadServiceTests.cs
@@ -10,7 +10,6 @@ public class DownloadServiceTests
// For the uninitiated with xUnit: This is initialized before every test.
private readonly DownloadService _downloadService;
private readonly LocalHttpServer _httpServer;
- private readonly TemporaryFileManager _temporaryFileManager;
private IReadOnlyCollection _downloadTasks;
public DownloadServiceTests(DownloadService downloadService,
@@ -18,7 +17,6 @@ public DownloadServiceTests(DownloadService downloadService,
{
_httpServer = httpServer;
_downloadService = downloadService;
- _temporaryFileManager = temporaryFileManager;
}
[Fact]
@@ -51,8 +49,8 @@ public async Task AddTask_Uri_ShouldDownload()
DownloadTaskStatus.Downloading,
DownloadTaskStatus.Completed);
- task.DownloadLocation.FileExists.Should().BeTrue();
- (await task.DownloadLocation.ReadAllTextAsync()).Should().Be("Hello, World!");
+ // File is deleted after Analyzing and repacking
+ task.DownloadPath.FileExists.Should().BeFalse();
task.Downloaded.Value.Should().BeGreaterThan(0);
}
@@ -106,8 +104,8 @@ public async Task CanSuspendDownloads()
DownloadTaskStatus.Downloading,
DownloadTaskStatus.Completed);
- task.DownloadLocation.FileExists.Should().BeTrue();
- (await task.DownloadLocation.ReadAllTextAsync()).Should().Be("Suspended Test");
+ // File is deleted after Analyzing and repacking
+ task.DownloadPath.FileExists.Should().BeFalse();
task.Downloaded.Value.Should().BeGreaterThan(0);
}
diff --git a/tests/Networking/NexusMods.Networking.Downloaders.Tests/Startup.cs b/tests/Networking/NexusMods.Networking.Downloaders.Tests/Startup.cs
index a5d414c227..a4c97f8c8a 100644
--- a/tests/Networking/NexusMods.Networking.Downloaders.Tests/Startup.cs
+++ b/tests/Networking/NexusMods.Networking.Downloaders.Tests/Startup.cs
@@ -1,11 +1,13 @@
using Microsoft.Extensions.DependencyInjection;
using NexusMods.Abstractions.GuidedInstallers;
using NexusMods.Abstractions.Serialization;
+using NexusMods.Abstractions.Settings;
using NexusMods.App.BuildInfo;
using NexusMods.Games.FOMOD;
using NexusMods.Games.Generic;
using NexusMods.Games.RedEngine;
using NexusMods.Games.TestFramework;
+using NexusMods.Paths;
using NexusMods.StandardGameLocators.TestHelpers;
namespace NexusMods.Networking.Downloaders.Tests;
@@ -14,6 +16,9 @@ public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
+ const KnownPath baseKnownPath = KnownPath.EntryDirectory;
+ var baseDirectory = $"NexusMods.Downloaders.Tests-{Guid.NewGuid()}";
+
services
.AddSingleton()
.AddDefaultServicesForTesting()
@@ -24,6 +29,10 @@ public void ConfigureServices(IServiceCollection services)
.AddSerializationAbstractions()
.AddFomod()
.AddDownloaders()
+ .OverrideSettingsForTests(settings => settings with
+ {
+ OngoingDownloadLocation = new ConfigurablePath(baseKnownPath, $"{baseDirectory}/Downloads/Ongoing"),
+ })
.AddSingleton()
.Validate();
}
diff --git a/tests/Networking/NexusMods.Networking.HttpDownloader.Tests/AdvancedHttpDownloaderTests.cs b/tests/Networking/NexusMods.Networking.HttpDownloader.Tests/AdvancedHttpDownloaderTests.cs
index 987dc13a23..68ea59f931 100644
--- a/tests/Networking/NexusMods.Networking.HttpDownloader.Tests/AdvancedHttpDownloaderTests.cs
+++ b/tests/Networking/NexusMods.Networking.HttpDownloader.Tests/AdvancedHttpDownloaderTests.cs
@@ -70,7 +70,7 @@ public async Task CanResumeDownload()
var downloadTask = _httpDownloader.DownloadAsync(sources,path, token: tokenSource.Token);
var progressFile = DownloadState.GetStateFilePath(path.Path);
- var downloadingFile = DownloadState.GetTempFilePath(path.Path);
+ var downloadingFile = DownloadState.GetProgressFilePath(path.Path);
while (!progressFile.FileExists)
await Task.Delay(10);