Embedded Blazor's script into the app, since .NET 10 moved it out of the framework

This commit is contained in:
Thorsten Sommer committed 2026-11-01 13:41:23 +01:00
1 parent b9639348e3
commit 6d1ece1fbc
3 files changed
+92 -2

No files matched your search

+32 -2
View File
@@ -1,3 +1,6 @@
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using AIStudio.Assistants.ERI;
using AIStudio.Tools;
@@ -6,12 +9,15 @@ using Changelog = AIStudio.Components.Changelog;
namespace AIStudio.Tests.Tools.AppAccess;
/// <summary>
/// Checks that the app reads the files below wwwroot which it shows itself.
/// Checks that the app reads the files below wwwroot which it shows itself, and that the release
/// can serve every file which the page of the app loads.
/// </summary>
/// <remarks>
/// The changelogs and the ERI specifications come from the files embedded into the app, not from a
/// request to its own server. A file which is missing there would leave the changelog or the ERI
/// assistant empty without any error.
/// assistant empty without any error. The release serves its static files from the same embedded
/// files; one which is missing there leaves the window without styles, or without any interaction
/// at all, while a debug build keeps working.
/// </remarks>
[TestFixture]
public sealed class WebRootFilesTests
@@ -20,6 +26,30 @@ public sealed class WebRootFilesTests
private static IEnumerable<ERIVersion> SpecificationVersions() => Enum.GetValues<ERIVersion>().Where(version => version.WasSpecificationSelected());
private static string ReadAppPageSource([CallerFilePath] string sourceFilePath = "") => File.ReadAllText(Path.Combine(Path.GetDirectoryName(sourceFilePath)!, "..", "..", "..", "MindWork AI Studio", "App.razor"));
/// <summary>
/// Reads the scripts and style sheets which App.razor loads from the app itself, so that a new one
/// is checked without anybody having to add it to a test.
/// </summary>
private static IEnumerable<string> FilesOfTheAppPage() => Regex.Matches(ReadAppPageSource(), @"<(?:script|link)\b[^>]*\b(?:src|href)=""(?<path>[^""]+)""")
.Select(match => match.Groups["path"].Value)
.Where(path => !path.Contains("//", StringComparison.Ordinal));
[Test]
public void TheAppPageLoadsFilesOfTheApp()
{
Assert.That(FilesOfTheAppPage(), Does.Contain("_framework/blazor.web.js").And.Contain("app.css"), "The test no longer finds the scripts and style sheets in App.razor.");
}
[TestCaseSource(nameof(FilesOfTheAppPage))]
public void EveryFileOfTheAppPageIsEmbedded(string path)
{
var file = new WebRootFiles().FileProvider.GetFileInfo(path);
Assert.That(file.Exists, Is.True, $"The release would not serve '{path}', since it is not among the embedded files.");
Assert.That(file.Length, Is.GreaterThan(0), $"The release would serve '{path}' as an empty file.");
}
[TestCaseSource(nameof(ChangelogFiles))]
public async Task EveryChangelogCanBeRead(string filename)
{
@@ -0,0 +1,29 @@
using System.Reflection;
using AIStudio.Tools.PluginSystem;
using Microsoft.Extensions.FileProviders;
namespace AIStudio.Tests.Tools.PluginSystem;
/// <summary>
/// Checks that the release finds the plugins which ship with AI Studio, such as the language plugins.
/// </summary>
/// <remarks>
/// A debug build reads these plugins from the source tree, while the release copies them out of the
/// files embedded into the app. A plugin which is missing there would leave the release without its
/// language, and only an error in the log would tell.
/// </remarks>
[TestFixture]
public sealed class InternalPluginResourcesTests
{
[Test]
public void EveryInternalPluginIsEmbedded([Values] InternalPlugin plugin)
{
var embeddedPlugins = new ManifestEmbeddedFileProvider(Assembly.GetAssembly(type: typeof(Program))!, "Plugins");
var mainFile = embeddedPlugins.GetFileInfo($"{plugin.MetaData().ResourcePath}/plugin.lua");
Assert.That(mainFile.Exists, Is.True, $"The release would not find the plugin {plugin}, since it is not among the embedded files.");
Assert.That(mainFile.Length, Is.GreaterThan(0), $"The release would find the plugin {plugin} empty.");
}
}