diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fda3b7..ebe3cd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added unit tests for `GitHubModSource.ListPlugins` to increase coverage for deterministic behavior. - **JSON Source Generation (AOT Support)**: Centralized registry in `AppJsonContext.cs` for all serialized models (`AuthResponse`, `DebugLogPayload`, `RalphTaskStatus`, `AssetModMetadata`, etc.) to ensure stability in trimmed builds. - `global.json`: Pinned .NET SDK to 9.0.313 for build reproducibility and to bypass broken preview SDKs. - `DESIGN.md` documenting the **Terminal Core** design system (colors, typography, layout grid, component specs, forbidden patterns). diff --git a/build/scripts/linux/build-avalonia-packages.sh b/build/scripts/linux/build-avalonia-packages.sh index 6a35814..8a3b868 100644 --- a/build/scripts/linux/build-avalonia-packages.sh +++ b/build/scripts/linux/build-avalonia-packages.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" PROJECT_PATH="$REPO_ROOT/src/GregModmanager.Avalonia/GregModmanager.Avalonia.csproj" OUTPUT_ROOT="${1:-$REPO_ROOT/artifacts/avalonia-linux}" VERSION="${2:-1.1.0}" diff --git a/src/GregModmanager.Avalonia/App.axaml.cs b/src/GregModmanager.Avalonia/App.axaml.cs index 08ae8af..617c088 100644 --- a/src/GregModmanager.Avalonia/App.axaml.cs +++ b/src/GregModmanager.Avalonia/App.axaml.cs @@ -21,13 +21,12 @@ public override void OnFrameworkInitializationCompleted() var telemetry = Services.GetRequiredService(); _ = telemetry.ReportCrashesAsync(); - _ = telemetry.TrackEventAsync("startup", new - { - steamActive = GregModmanager.Steam.SteamApiNativeLoader.IsLoaded, - culture = System.Globalization.CultureInfo.CurrentCulture.Name, - osDescription = System.Runtime.InteropServices.RuntimeInformation.OSDescription, - dotNetVersion = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription - }); + _ = telemetry.TrackEventAsync("startup", new GregModmanager.Models.StartupEvent( + GregModmanager.Steam.SteamApiNativeLoader.IsLoaded, + System.Globalization.CultureInfo.CurrentCulture.Name, + System.Runtime.InteropServices.RuntimeInformation.OSDescription, + System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription + )); if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { diff --git a/src/GregModmanager.Core/Models/AppJsonContext.cs b/src/GregModmanager.Core/Models/AppJsonContext.cs index d7fe96d..6bd64ad 100644 --- a/src/GregModmanager.Core/Models/AppJsonContext.cs +++ b/src/GregModmanager.Core/Models/AppJsonContext.cs @@ -34,6 +34,7 @@ namespace GregModmanager.Models; [JsonSerializable(typeof(int))] [JsonSerializable(typeof(RalphTaskStatus))] [JsonSerializable(typeof(AssetModMetadata))] +[JsonSerializable(typeof(StartupEvent))] public partial class AppJsonContext : JsonSerializerContext { } diff --git a/src/GregModmanager.Core/Models/StartupEvent.cs b/src/GregModmanager.Core/Models/StartupEvent.cs new file mode 100644 index 0000000..e73c1cc --- /dev/null +++ b/src/GregModmanager.Core/Models/StartupEvent.cs @@ -0,0 +1,8 @@ +namespace GregModmanager.Models; + +public sealed record StartupEvent( + bool SteamActive, + string Culture, + string OsDescription, + string DotNetVersion +); diff --git a/src/GregModmanager.Core/Services/TelemetryService.cs b/src/GregModmanager.Core/Services/TelemetryService.cs index 8531b66..cb6d478 100644 --- a/src/GregModmanager.Core/Services/TelemetryService.cs +++ b/src/GregModmanager.Core/Services/TelemetryService.cs @@ -99,7 +99,8 @@ public async Task TrackEventAsync(string eventName, object payload, Dictionary JsonSerializer.Serialize(sync, AppJsonContext.Default.SyncCollectionEvent), - _ => JsonSerializer.Serialize(payload, payload.GetType(), AppJsonContext.Default.Options) + StartupEvent start => JsonSerializer.Serialize(start, AppJsonContext.Default.StartupEvent), + _ => "{}" }; await PushToLokiAsync(eventName, message, labels); diff --git a/tests/GregModmanager.Tests/GitHubModSourceTests.cs b/tests/GregModmanager.Tests/GitHubModSourceTests.cs new file mode 100644 index 0000000..15d1305 --- /dev/null +++ b/tests/GregModmanager.Tests/GitHubModSourceTests.cs @@ -0,0 +1,35 @@ +using System.Linq; +using Xunit; +using GregModmanager.Services; + +namespace GregModmanager.Tests; + +public class GitHubModSourceTests +{ + [Fact] + public void ListPlugins_ReturnsExpectedHardcodedPlugins() + { + // Arrange + var source = new GitHubModSource(); + + // Act + var plugins = source.ListPlugins(); + + // Assert + Assert.NotNull(plugins); + Assert.Equal(4, plugins.Count); + + // Verify the generated PluginIds + Assert.Equal("gregCore", plugins[0].PluginId); + Assert.Equal("gregMod.IPAM", plugins[1].PluginId); + Assert.Equal("gregMod.ResetSwitch", plugins[2].PluginId); + Assert.Equal("SteamPlugin", plugins[3].PluginId); // Mapped from "-DataCenter-ModLoader" + + // Verify common properties for all returned plugins + foreach (var plugin in plugins) + { + Assert.Equal("Latest (GitHub)", plugin.Version); + Assert.Equal("github", plugin.Channel); + } + } +}