mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
160 lines
6.3 KiB
C#
160 lines
6.3 KiB
C#
using System.IO.Compression;
|
|
using LanMountainDesktop.PluginPackaging;
|
|
using LanMountainDesktop.PluginSdk;
|
|
using LanMountainDesktop.Services;
|
|
using Xunit;
|
|
|
|
namespace LanMountainDesktop.Tests;
|
|
|
|
public sealed class PendingPluginUpgradeServiceTests : IDisposable
|
|
{
|
|
private readonly string _tempRoot = Path.Combine(
|
|
Path.GetTempPath(),
|
|
"LanMountainDesktop.Tests",
|
|
nameof(PendingPluginUpgradeServiceTests),
|
|
Guid.NewGuid().ToString("N"));
|
|
|
|
[Fact]
|
|
public void AddPendingInstallOrUpgrade_ReplacesExistingOperationForSamePlugin()
|
|
{
|
|
var pluginsDirectory = CreatePluginsDirectory();
|
|
var firstPackage = CreatePluginPackage("first.laapp", "plugin.queue.sample", "Sample Plugin", "1.0.0");
|
|
var secondPackage = CreatePluginPackage("second.laapp", "plugin.queue.sample", "Sample Plugin", "2.0.0");
|
|
var service = new PendingPluginUpgradeService(pluginsDirectory);
|
|
|
|
service.AddPendingInstallOrUpgrade("plugin.queue.sample", firstPackage, "1.0.0");
|
|
service.AddPendingInstallOrUpgrade("plugin.queue.sample", secondPackage, "2.0.0");
|
|
|
|
var pending = service.GetPendingUpgrades();
|
|
var operation = Assert.Single(pending);
|
|
Assert.Equal("plugin.queue.sample", operation.PluginId);
|
|
Assert.Equal("2.0.0", operation.TargetVersion);
|
|
Assert.Equal(PendingPluginOperation.InstallOrUpgrade, operation.Operation);
|
|
Assert.Equal(Path.GetFullPath(secondPackage), operation.SourcePackagePath);
|
|
}
|
|
|
|
[Fact]
|
|
public void ApplyPendingOperations_InstallsPackageAndClearsSuccessfulOperation()
|
|
{
|
|
var pluginsDirectory = CreatePluginsDirectory();
|
|
var packagePath = CreatePluginPackage("sample.laapp", "plugin.install.queue", "Queued Plugin", "1.0.0");
|
|
var service = new PendingPluginUpgradeService(pluginsDirectory);
|
|
service.AddPendingInstallOrUpgrade("plugin.install.queue", packagePath, "1.0.0");
|
|
|
|
var result = service.ApplyPendingOperations();
|
|
|
|
Assert.Equal(1, result.SuccessCount);
|
|
Assert.Equal(0, result.FailureCount);
|
|
Assert.True(File.Exists(Path.Combine(pluginsDirectory, "plugin.install.queue.laapp")));
|
|
Assert.Empty(service.GetPendingUpgrades());
|
|
}
|
|
|
|
[Fact]
|
|
public void ApplyPendingOperations_ReplacesExistingPackageWithSamePluginId()
|
|
{
|
|
var pluginsDirectory = CreatePluginsDirectory();
|
|
var firstPackage = CreatePluginPackage("first.laapp", "plugin.replace.queue", "Old Plugin", "1.0.0");
|
|
var secondPackage = CreatePluginPackage("second.laapp", "plugin.replace.queue", "New Plugin", "2.0.0");
|
|
File.Copy(firstPackage, Path.Combine(pluginsDirectory, "plugin.replace.queue.laapp"));
|
|
|
|
var service = new PendingPluginUpgradeService(pluginsDirectory);
|
|
service.AddPendingInstallOrUpgrade("plugin.replace.queue", secondPackage, "2.0.0");
|
|
|
|
var result = service.ApplyPendingOperations();
|
|
|
|
Assert.Equal(1, result.SuccessCount);
|
|
var installedPackages = Directory.EnumerateFiles(pluginsDirectory, "*.laapp", SearchOption.TopDirectoryOnly).ToArray();
|
|
var installedPackage = Assert.Single(installedPackages);
|
|
var manifest = ReadManifestFromPackage(installedPackage);
|
|
Assert.Equal("plugin.replace.queue", manifest.Id);
|
|
Assert.Equal("New Plugin", manifest.Name);
|
|
Assert.Equal("2.0.0", manifest.Version);
|
|
}
|
|
|
|
[Fact]
|
|
public void ApplyPendingOperations_KeepsFailedOperationQueued()
|
|
{
|
|
var pluginsDirectory = CreatePluginsDirectory();
|
|
var invalidPackage = Path.Combine(_tempRoot, "invalid.laapp");
|
|
Directory.CreateDirectory(_tempRoot);
|
|
using (ZipFile.Open(invalidPackage, ZipArchiveMode.Create))
|
|
{
|
|
}
|
|
|
|
var service = new PendingPluginUpgradeService(pluginsDirectory);
|
|
service.AddPendingInstallOrUpgrade("plugin.invalid.queue", invalidPackage, "1.0.0");
|
|
|
|
var result = service.ApplyPendingOperations();
|
|
|
|
Assert.Equal(0, result.SuccessCount);
|
|
Assert.Equal(1, result.FailureCount);
|
|
Assert.Single(service.GetPendingUpgrades());
|
|
}
|
|
|
|
[Fact]
|
|
public void ApplyPendingOperations_KeepsMissingPackageOperationQueued()
|
|
{
|
|
var pluginsDirectory = CreatePluginsDirectory();
|
|
var missingPackage = Path.Combine(_tempRoot, "missing.laapp");
|
|
var service = new PendingPluginUpgradeService(pluginsDirectory);
|
|
service.AddPendingInstallOrUpgrade("plugin.missing.queue", missingPackage, "1.0.0");
|
|
|
|
var result = service.ApplyPendingOperations();
|
|
|
|
Assert.Equal(0, result.SuccessCount);
|
|
Assert.Equal(1, result.FailureCount);
|
|
Assert.Single(service.GetPendingUpgrades());
|
|
}
|
|
|
|
private string CreatePluginsDirectory()
|
|
{
|
|
var directory = Path.Combine(_tempRoot, "Extensions", "Plugins");
|
|
Directory.CreateDirectory(directory);
|
|
return directory;
|
|
}
|
|
|
|
private string CreatePluginPackage(string fileName, string pluginId, string pluginName, string version)
|
|
{
|
|
Directory.CreateDirectory(_tempRoot);
|
|
var packagePath = Path.Combine(_tempRoot, fileName);
|
|
using var archive = ZipFile.Open(packagePath, ZipArchiveMode.Create);
|
|
var entry = archive.CreateEntry(PluginSdkInfo.ManifestFileName);
|
|
using var stream = entry.Open();
|
|
using var writer = new StreamWriter(stream);
|
|
writer.Write(
|
|
$$"""
|
|
{
|
|
"id": "{{pluginId}}",
|
|
"name": "{{pluginName}}",
|
|
"version": "{{version}}",
|
|
"apiVersion": "5.0.0",
|
|
"entranceAssembly": "{{pluginId}}.dll"
|
|
}
|
|
""");
|
|
return packagePath;
|
|
}
|
|
|
|
private static LanMountainDesktop.PluginSdk.PluginManifest ReadManifestFromPackage(string packagePath)
|
|
{
|
|
using var archive = ZipFile.OpenRead(packagePath);
|
|
var entry = archive.GetEntry(PluginSdkInfo.ManifestFileName)
|
|
?? throw new InvalidOperationException("Missing plugin manifest.");
|
|
using var stream = entry.Open();
|
|
return LanMountainDesktop.PluginSdk.PluginManifest.Load(stream, $"{packagePath}!/{entry.FullName}");
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
try
|
|
{
|
|
if (Directory.Exists(_tempRoot))
|
|
{
|
|
Directory.Delete(_tempRoot, recursive: true);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
}
|