Files
lmxopcua/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Raw/AdminUiFormSweepGuardTests.cs
T

61 lines
2.6 KiB
C#

using Shouldly;
using Xunit;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Raw;
/// <summary>
/// Issue #604 source-scan guards (Razor has no bUnit): an <c>EditForm</c> with a validator but nothing
/// to show its messages is a silent no-op Save, the layout must keep its error boundary, and the
/// API-key Delete must not fire straight from the row button.
/// </summary>
public sealed class AdminUiFormSweepGuardTests
{
/// <summary>EditForm pages whose validation messages are rendered by a child/section component.</summary>
private static readonly HashSet<string> AllowList = new(StringComparer.Ordinal);
[Fact]
public void Every_razor_with_an_EditForm_and_a_DataAnnotationsValidator_renders_validation_messages()
{
var offenders = new List<string>();
foreach (var file in Directory.EnumerateFiles(ComponentsDir(), "*.razor", SearchOption.AllDirectories))
{
var text = File.ReadAllText(file);
if (!text.Contains("<EditForm") || !text.Contains("<DataAnnotationsValidator")) { continue; }
if (text.Contains("<ValidationSummary") || text.Contains("<ValidationMessage")) { continue; }
var name = Path.GetRelativePath(ComponentsDir(), file).Replace('\\', '/');
if (!AllowList.Contains(name)) { offenders.Add(name); }
}
offenders.ShouldBeEmpty("these forms validate but never show a message: " + string.Join(", ", offenders));
}
[Fact]
public void MainLayout_wraps_the_body_in_an_ErrorBoundary()
{
var text = File.ReadAllText(Path.Combine(ComponentsDir(), "Layout", "MainLayout.razor"));
var boundary = text.IndexOf("<ErrorBoundary", StringComparison.Ordinal);
boundary.ShouldBeGreaterThan(-1);
text.IndexOf("@Body", StringComparison.Ordinal).ShouldBeGreaterThan(boundary);
}
[Fact]
public void ApiKeys_delete_button_goes_through_the_confirm_dialog()
{
var text = File.ReadAllText(Path.Combine(ComponentsDir(), "Pages", "ApiKeys.razor"));
text.ShouldContain("<RawConfirmDialog");
text.ShouldNotContain("DeleteAsync(k.ApiKeyId)");
}
private static string ComponentsDir()
{
var dir = new DirectoryInfo(AppContext.BaseDirectory);
while (dir is not null)
{
var candidate = Path.Combine(dir.FullName, "src", "Server", "ZB.MOM.WW.OtOpcUa.AdminUI", "Components");
if (Directory.Exists(candidate)) { return candidate; }
dir = dir.Parent;
}
throw new DirectoryNotFoundException("AdminUI Components directory not found above the test binaries.");
}
}