fix. 插件安装修复

This commit is contained in:
lincube
2026-06-01 01:12:52 +08:00
parent c351a8e7f3
commit a2ac302ee7
18 changed files with 515 additions and 130 deletions

View File

@@ -0,0 +1,35 @@
using LanMountainDesktop.Launcher.Models;
using Xunit;
namespace LanMountainDesktop.Tests;
public sealed class DataLocationResolverTests : IDisposable
{
private readonly string _appRoot = Path.Combine(
Path.GetTempPath(),
"LanMountainDesktop.Tests",
nameof(DataLocationResolverTests),
Guid.NewGuid().ToString("N"));
[Fact]
public void ApplyLocationChoice_PortableWithoutCustomPath_UsesAppRootDesktopDirectory()
{
Directory.CreateDirectory(_appRoot);
var resolver = new DataLocationResolver(_appRoot);
var applied = resolver.ApplyLocationChoice(DataLocationMode.Portable);
Assert.True(applied);
Assert.Equal(
Path.Combine(Path.GetFullPath(_appRoot), "Desktop"),
resolver.ResolveDataRoot());
}
public void Dispose()
{
if (Directory.Exists(_appRoot))
{
Directory.Delete(_appRoot, recursive: true);
}
}
}

View File

@@ -1,5 +1,6 @@
using LanMountainDesktop.Launcher.Plugins;
using System.IO.Compression;
using System.Text.Json;
using Xunit;
namespace LanMountainDesktop.Tests;
@@ -34,10 +35,10 @@ public sealed class PluginInstallerServiceTests : IDisposable
Directory.CreateDirectory(_tempRoot);
CreatePluginPackage(packagePath, "plugin.json", "plugin.install.sample", "Sample Plugin");
var pluginsDirectory = CreateUserScopedPluginsDirectory();
var pluginsDirectory = CreateConfiguredPortablePluginsDirectory(out var appRoot);
var service = new PluginInstallerService();
var result = service.InstallPackage(packagePath, pluginsDirectory);
var result = service.InstallPackage(packagePath, pluginsDirectory, appRoot);
Assert.True(result.Success);
Assert.Equal("ok", result.Code);
@@ -49,6 +50,42 @@ public sealed class PluginInstallerServiceTests : IDisposable
Assert.Empty(Directory.EnumerateFiles(pluginsDirectory, "*.incoming", SearchOption.AllDirectories));
}
[Fact]
public void InstallPackage_AllowsConfiguredPortableDataRootOutsideUserScope()
{
if (!OperatingSystem.IsWindows())
{
return;
}
Directory.CreateDirectory(_tempRoot);
var appRoot = Path.Combine(_tempRoot, "PackageRoot");
var portableDataRoot = Path.Combine(appRoot, "Desktop");
var launcherDataRoot = Path.Combine(appRoot, ".Launcher");
Directory.CreateDirectory(launcherDataRoot);
File.WriteAllText(
Path.Combine(launcherDataRoot, "data-location.config.json"),
JsonSerializer.Serialize(new
{
DataLocationMode = "Portable",
SystemDataPath = Path.Combine(_tempRoot, "System"),
PortableDataPath = portableDataRoot
}));
var packagePath = Path.Combine(_tempRoot, "portable.laapp");
CreatePluginPackage(packagePath, "plugin.json", "plugin.portable.sample", "Portable Plugin");
var pluginsDirectory = Path.Combine(portableDataRoot, "Extensions", "Plugins");
var service = new PluginInstallerService();
var result = service.InstallPackage(packagePath, pluginsDirectory, appRoot);
Assert.True(result.Success);
Assert.Equal("ok", result.Code);
Assert.True(File.Exists(result.InstalledPackagePath));
Assert.StartsWith(Path.GetFullPath(portableDataRoot), Path.GetFullPath(result.InstalledPackagePath!), StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void InstallPackage_ReplacesExistingPackageWithSamePluginId()
{
@@ -58,11 +95,11 @@ public sealed class PluginInstallerServiceTests : IDisposable
CreatePluginPackage(firstPackagePath, "plugin.json", "plugin.replace.sample", "Sample Plugin v1");
CreatePluginPackage(secondPackagePath, "plugin.json", "plugin.replace.sample", "Sample Plugin v2");
var pluginsDirectory = CreateUserScopedPluginsDirectory();
var pluginsDirectory = CreateConfiguredPortablePluginsDirectory(out var appRoot);
var service = new PluginInstallerService();
var first = service.InstallPackage(firstPackagePath, pluginsDirectory);
var second = service.InstallPackage(secondPackagePath, pluginsDirectory);
var first = service.InstallPackage(firstPackagePath, pluginsDirectory, appRoot);
var second = service.InstallPackage(secondPackagePath, pluginsDirectory, appRoot);
Assert.True(first.Success);
Assert.True(second.Success);
@@ -77,10 +114,10 @@ public sealed class PluginInstallerServiceTests : IDisposable
Directory.CreateDirectory(_tempRoot);
CreatePluginPackage(packagePath, "manifest.json", "plugin.legacy.sample", "Legacy Plugin");
var pluginsDirectory = CreateUserScopedPluginsDirectory();
var pluginsDirectory = CreateConfiguredPortablePluginsDirectory(out var appRoot);
var service = new PluginInstallerService();
var result = service.InstallPackage(packagePath, pluginsDirectory);
var result = service.InstallPackage(packagePath, pluginsDirectory, appRoot);
Assert.True(result.Success);
Assert.Equal("plugin.legacy.sample", result.ManifestId);
@@ -103,18 +140,24 @@ public sealed class PluginInstallerServiceTests : IDisposable
""");
}
private static string CreateUserScopedPluginsDirectory()
private string CreateConfiguredPortablePluginsDirectory(out string appRoot)
{
var root = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"LanMountainDesktop",
"Tests",
nameof(PluginInstallerServiceTests),
Guid.NewGuid().ToString("N"),
"Extensions",
"Plugins");
Directory.CreateDirectory(root);
return root;
appRoot = Path.Combine(_tempRoot, "ConfiguredPackageRoot", Guid.NewGuid().ToString("N"));
var portableDataRoot = Path.Combine(appRoot, "Desktop");
var launcherDataRoot = Path.Combine(appRoot, ".Launcher");
Directory.CreateDirectory(launcherDataRoot);
File.WriteAllText(
Path.Combine(launcherDataRoot, "data-location.config.json"),
JsonSerializer.Serialize(new
{
DataLocationMode = "Portable",
SystemDataPath = Path.Combine(_tempRoot, "System"),
PortableDataPath = portableDataRoot
}));
var pluginsDirectory = Path.Combine(portableDataRoot, "Extensions", "Plugins");
Directory.CreateDirectory(pluginsDirectory);
return pluginsDirectory;
}
public void Dispose()

View File

@@ -0,0 +1,40 @@
using LanMountainDesktop.Services;
using Xunit;
namespace LanMountainDesktop.Tests;
public sealed class PluginRuntimeDataPathTests : IDisposable
{
private readonly string _dataRoot = Path.Combine(
Path.GetTempPath(),
"LanMountainDesktop.Tests",
nameof(PluginRuntimeDataPathTests),
Guid.NewGuid().ToString("N"));
[Fact]
public void PluginRuntime_UsesHostDataRootForPluginsAndMarketData()
{
AppDataPathProvider.Initialize(["--data-root", _dataRoot]);
using var runtime = new PluginRuntimeService();
Assert.Equal(
Path.Combine(Path.GetFullPath(_dataRoot), "Extensions", "Plugins"),
runtime.PluginsDirectory);
}
public void Dispose()
{
AppDataPathProvider.ResetForTests();
try
{
if (Directory.Exists(_dataRoot))
{
Directory.Delete(_dataRoot, recursive: true);
}
}
catch
{
}
}
}