Files
ScadaBridge/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Shared/TreeViewStorageResilienceTests.cs
T
Joseph Doherty 513fa1aa16 docs(tests): fix CommentChecker findings across tests/ — 13,392 → 0 (repo-wide scan clean)
Comment/XML-doc changes only:
- add summaries to ~10k test methods, fixtures, fakes and helpers
  (+ <param> on theories, <returns> on async Task methods,
  <inheritdoc/> on interface implementations the checker can resolve)
- strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N,
  #NN, Component-0NN) from comments, keeping the explanatory text;
  reword false positives in comments only
- real docs on fakes implementing BCL/library interfaces
  (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime)
- reword the last 5 src/ false positives (CWE-1236, failures-1,
  year-0001, M365)

Only non-comment edits: four one-line nested classes split across lines
so members can carry docs. Build 0 errors / 0 warnings.
2026-10-07 15:05:49 -04:00

65 lines
2.7 KiB
C#

using Bunit;
using Microsoft.AspNetCore.Components;
using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Shared;
/// <summary>
/// Regression tests for <c>TreeView</c>'s storage-restore path
/// called <c>JsonSerializer.Deserialize</c> on the raw <c>treeviewStorage</c>
/// payload outside any try block — a corrupt payload threw an uncaught
/// <c>JsonException</c> during <c>OnAfterRenderAsync</c>, breaking the
/// component. The fix guards the deserialize and ignores a corrupt payload.
/// </summary>
public class TreeViewStorageResilienceTests : BunitContext
{
private record TestNode(string Key, string Label, List<TestNode> Children);
private static List<TestNode> Roots() => new()
{
new("a", "Alpha", new() { new("a1", "Alpha-1", new()) }),
new("b", "Beta", new()),
};
private IRenderedComponent<TreeView<TestNode>> BuildTree()
=> Render<TreeView<TestNode>>(parameters => parameters
.Add(p => p.Items, Roots())
.Add(p => p.ChildrenSelector, n => n.Children)
.Add(p => p.HasChildrenSelector, n => n.Children.Count > 0)
.Add(p => p.KeySelector, n => n.Key)
.Add(p => p.NodeContent, (RenderFragment<TestNode>)(node => b =>
b.AddMarkupContent(0, $"<span>{node.Label}</span>")))
.Add(p => p.StorageKey, "corrupt-tree"));
/// <summary>Verifies that restoring a corrupt JSON payload from storage does not throw and the tree still renders.</summary>
[Fact]
public void StorageRestore_CorruptJsonPayload_DoesNotThrow_AndStillRenders()
{
// A garbage payload that is not valid JSON for a List<string>.
JSInterop.Setup<string?>("treeviewStorage.load", _ => true)
.SetResult("{not json at all]");
JSInterop.SetupVoid("treeviewStorage.save", _ => true).SetVoidResult();
// Pre-fix: OnAfterRenderAsync threw JsonException out of the unguarded
// Deserialize call. Post-fix: the corrupt payload is ignored.
var cut = BuildTree();
Assert.Contains("Alpha", cut.Markup);
Assert.Contains("Beta", cut.Markup);
}
/// <summary>Verifies that restoring JSON of the wrong shape from storage does not throw.</summary>
[Fact]
public void StorageRestore_WrongShapeJson_DoesNotThrow()
{
// Valid JSON, but not a List<string> — an object, not an array.
JSInterop.Setup<string?>("treeviewStorage.load", _ => true)
.SetResult("{\"unexpected\": true}");
JSInterop.SetupVoid("treeviewStorage.save", _ => true).SetVoidResult();
var cut = BuildTree();
Assert.Contains("Alpha", cut.Markup);
}
}