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.
This commit is contained in:
@@ -6,7 +6,7 @@ using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
|
||||
/// <summary>
|
||||
/// MV-13: the shared <c>AttributeListEditor</c> reveals an element-type select
|
||||
/// The shared <c>AttributeListEditor</c> reveals an element-type select
|
||||
/// plus a repeatable list-value editor for structured List attributes. These are
|
||||
/// real bUnit rendering/interaction tests over the self-contained component, plus
|
||||
/// structural assertions pinning the TemplateEdit attribute-form wiring (the page
|
||||
@@ -29,12 +29,13 @@ public class AttributeListEditorTests : BunitContext
|
||||
private static string TemplateEditMarkup
|
||||
=> File.ReadAllText(Path.Combine(DesignComponentsRoot, "TemplateEdit.razor"));
|
||||
|
||||
// M10 residual: the attribute authoring form moved out of the page into the
|
||||
// The attribute authoring form moved out of the page into the
|
||||
// dialog body component hosted by IDialogService.ShowAsync. Submit-side
|
||||
// encoding stays on the page (it owns TemplateService).
|
||||
private static string AttributeDialogMarkup
|
||||
=> File.ReadAllText(Path.Combine(DesignComponentsRoot, "TemplateAttributeDialog.razor"));
|
||||
|
||||
/// <summary>Verifies that the editor renders an element type select offering the six valid scalar types.</summary>
|
||||
[Fact]
|
||||
public void Editor_RendersElementTypeSelect_WithSixValidScalars()
|
||||
{
|
||||
@@ -56,6 +57,7 @@ public class AttributeListEditorTests : BunitContext
|
||||
Assert.DoesNotContain("List", texts);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that turning off the element type option hides the select.</summary>
|
||||
[Fact]
|
||||
public void ShowElementType_False_HidesTheSelect()
|
||||
{
|
||||
@@ -66,6 +68,7 @@ public class AttributeListEditorTests : BunitContext
|
||||
Assert.Throws<ElementNotFoundException>(() => cut.Find("select.form-select"));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the editor renders one input per row.</summary>
|
||||
[Fact]
|
||||
public void Editor_RendersOneInputPerRow()
|
||||
{
|
||||
@@ -79,6 +82,7 @@ public class AttributeListEditorTests : BunitContext
|
||||
Assert.Equal("3", inputs[2].GetAttribute("value"));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that adding an element appends a row and raises the rows-changed callback.</summary>
|
||||
[Fact]
|
||||
public void AddElement_AppendsRow_AndRaisesRowsChanged()
|
||||
{
|
||||
@@ -95,6 +99,7 @@ public class AttributeListEditorTests : BunitContext
|
||||
Assert.Equal("", changed[1]);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that removing an element drops its row and raises the rows-changed callback.</summary>
|
||||
[Fact]
|
||||
public void RemoveElement_DropsRow_AndRaisesRowsChanged()
|
||||
{
|
||||
@@ -112,6 +117,7 @@ public class AttributeListEditorTests : BunitContext
|
||||
Assert.Equal("b", changed![0]);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that encoded rows round-trip through the codec.</summary>
|
||||
[Fact]
|
||||
public void EncodedRows_RoundTripThroughCodec()
|
||||
{
|
||||
@@ -123,6 +129,7 @@ public class AttributeListEditorTests : BunitContext
|
||||
Assert.Equal(new[] { 10, 20 }, list);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the template edit form reveals the list editor and sends the element type.</summary>
|
||||
[Fact]
|
||||
public void TemplateEdit_RevealsListEditor_AndSendsElementType()
|
||||
{
|
||||
|
||||
+8
-2
@@ -13,7 +13,7 @@ using ExternalSystemForm = ZB.MOM.WW.ScadaBridge.CentralUI.Components.Pages.Desi
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
|
||||
/// <summary>
|
||||
/// Bundle D drill-in test (#23 M7-T12) for the External Systems edit page.
|
||||
/// Drill-in test for the External Systems edit page.
|
||||
/// The page-header chip routes operators into the central Audit Log
|
||||
/// pre-filtered by Target = external-system name. Create mode has nothing
|
||||
/// to drill into yet, so the link is suppressed.
|
||||
@@ -22,6 +22,7 @@ public class ExternalSystemFormAuditDrillinTests : BunitContext
|
||||
{
|
||||
private readonly IExternalSystemRepository _repo = Substitute.For<IExternalSystemRepository>();
|
||||
|
||||
/// <summary>Initializes the test context with a substitute repository and test authentication.</summary>
|
||||
public ExternalSystemFormAuditDrillinTests()
|
||||
{
|
||||
Services.AddSingleton(_repo);
|
||||
@@ -38,6 +39,7 @@ public class ExternalSystemFormAuditDrillinTests : BunitContext
|
||||
AuthorizationPolicies.AddScadaBridgeAuthorization(Services);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the edit page shows a recent audit activity link whose target equals the system name.</summary>
|
||||
[Fact]
|
||||
public void EditPage_HasRecentAuditActivityLink_WithTargetEqualToSystemName()
|
||||
{
|
||||
@@ -57,6 +59,7 @@ public class ExternalSystemFormAuditDrillinTests : BunitContext
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the create page shows no recent audit activity link.</summary>
|
||||
[Fact]
|
||||
public void CreatePage_HasNoRecentAuditActivityLink()
|
||||
{
|
||||
@@ -70,10 +73,11 @@ public class ExternalSystemFormAuditDrillinTests : BunitContext
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the form renders a timeout seconds input with the gateway default helper text.</summary>
|
||||
[Fact]
|
||||
public void Form_RendersTimeoutSecondsInput_WithGatewayDefaultHelperText()
|
||||
{
|
||||
// PLAN-06 Task 12: the per-system TimeoutSeconds column (Task 8) needs a
|
||||
// The per-system TimeoutSeconds column needs a
|
||||
// Central UI form field so Design users can actually set it.
|
||||
var cut = Render<ExternalSystemForm>();
|
||||
|
||||
@@ -84,6 +88,7 @@ public class ExternalSystemFormAuditDrillinTests : BunitContext
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Verifies that saving a new system passes its timeout seconds to the repository.</summary>
|
||||
[Fact]
|
||||
public void SavingNewSystem_WithTimeoutSeconds_PassesTimeoutSecondsToRepository()
|
||||
{
|
||||
@@ -105,6 +110,7 @@ public class ExternalSystemFormAuditDrillinTests : BunitContext
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Verifies that saving an edited system updates the timeout seconds on the existing record.</summary>
|
||||
[Fact]
|
||||
public void SavingEditedSystem_UpdatesTimeoutSecondsOnExisting()
|
||||
{
|
||||
|
||||
+2
@@ -25,6 +25,7 @@ public class ExternalSystemsConnectionStringHidingTests : BunitContext
|
||||
private readonly IInboundApiRepository _inbound = Substitute.For<IInboundApiRepository>();
|
||||
private readonly IDialogService _dialog = Substitute.For<IDialogService>();
|
||||
|
||||
/// <summary>Initializes the test context and registers the services the External Systems page depends on.</summary>
|
||||
public ExternalSystemsConnectionStringHidingTests()
|
||||
{
|
||||
Services.AddSingleton(_repo);
|
||||
@@ -43,6 +44,7 @@ public class ExternalSystemsConnectionStringHidingTests : BunitContext
|
||||
AuthorizationPolicies.AddScadaBridgeAuthorization(Services);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the database connections tab does not render the connection string.</summary>
|
||||
[Fact]
|
||||
public void DbConnectionsTab_DoesNotRenderConnectionString()
|
||||
{
|
||||
|
||||
+7
-1
@@ -7,7 +7,7 @@ using ZB.MOM.WW.ScadaBridge.CentralUI.Services;
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
|
||||
/// <summary>
|
||||
/// M9-T31 (+#261 follow-up): the raw-JSON escape hatch in
|
||||
/// The raw-JSON escape hatch in
|
||||
/// <see cref="ParameterValueForm"/> (the fallback for an unresolved <c>$ref</c> /
|
||||
/// unknown-type node) is a Monaco <c>json</c> editor wired with THAT FIELD's own
|
||||
/// sub-schema — not the whole root object schema — so each field's editor
|
||||
@@ -22,6 +22,7 @@ public class ParameterValueFormMonacoSchemaTests : BunitContext
|
||||
{
|
||||
private readonly ISchemaLibraryQueryService _library = Substitute.For<ISchemaLibraryQueryService>();
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="ParameterValueFormMonacoSchemaTests"/> class.</summary>
|
||||
public ParameterValueFormMonacoSchemaTests()
|
||||
{
|
||||
// The escape-hatch surface renders a MonacoEditor whose JS interop is not
|
||||
@@ -33,6 +34,7 @@ public class ParameterValueFormMonacoSchemaTests : BunitContext
|
||||
Services.AddSingleton(_library);
|
||||
}
|
||||
|
||||
/// <summary>Verifies the case: escape Hatch, renders Monaco Json Editor, not Plain Textarea.</summary>
|
||||
[Fact]
|
||||
public void EscapeHatch_RendersMonacoJsonEditor_NotPlainTextarea()
|
||||
{
|
||||
@@ -57,6 +59,7 @@ public class ParameterValueFormMonacoSchemaTests : BunitContext
|
||||
Assert.Empty(cut.FindAll("textarea"));
|
||||
}
|
||||
|
||||
/// <summary>Verifies the case: escape Hatch, monaco Editor, receives Field Sub Schema, not Root Schema.</summary>
|
||||
[Fact]
|
||||
public void EscapeHatch_MonacoEditor_ReceivesFieldSubSchema_NotRootSchema()
|
||||
{
|
||||
@@ -106,6 +109,7 @@ public class ParameterValueFormMonacoSchemaTests : BunitContext
|
||||
Assert.DoesNotContain("$ref", jsonSchema!);
|
||||
}
|
||||
|
||||
/// <summary>Verifies the case: escape Hatch, with Resolvable Sibling Object, scopes Field Editor To Its Own Fragment.</summary>
|
||||
[Fact]
|
||||
public void EscapeHatch_WithResolvableSiblingObject_ScopesFieldEditorToItsOwnFragment()
|
||||
{
|
||||
@@ -143,6 +147,7 @@ public class ParameterValueFormMonacoSchemaTests : BunitContext
|
||||
Assert.DoesNotContain("\"id\"", jsonSchema!);
|
||||
}
|
||||
|
||||
/// <summary>Verifies the case: multiple Escape Hatch Fields, each Editor Receives Its Own Field Fragment, not Root Schema.</summary>
|
||||
[Fact]
|
||||
public void MultipleEscapeHatchFields_EachEditorReceivesItsOwnFieldFragment_NotRootSchema()
|
||||
{
|
||||
@@ -182,6 +187,7 @@ public class ParameterValueFormMonacoSchemaTests : BunitContext
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Verifies the case: multiple Escape Hatch Fields, do Not Leak AResolvable Siblings Shape.</summary>
|
||||
[Fact]
|
||||
public void MultipleEscapeHatchFields_DoNotLeakAResolvableSiblingsShape()
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ using ZB.MOM.WW.ScadaBridge.CentralUI.Services;
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
|
||||
/// <summary>
|
||||
/// M9-T30: <c>ParameterValueForm</c> renders typed nested inputs for object and
|
||||
/// <c>ParameterValueForm</c> renders typed nested inputs for object and
|
||||
/// list parameters (replacing the raw-JSON textarea fallback), driven by the
|
||||
/// declared schema (with <c>{"$ref":"lib:Name"}</c> resolved via
|
||||
/// <see cref="ISchemaLibraryQueryService"/>), with per-field validation, and
|
||||
@@ -19,6 +19,7 @@ public class ParameterValueFormTests : BunitContext
|
||||
{
|
||||
private readonly ISchemaLibraryQueryService _library = Substitute.For<ISchemaLibraryQueryService>();
|
||||
|
||||
/// <summary>Initializes a new instance of the <c>ParameterValueFormTests</c> class.</summary>
|
||||
public ParameterValueFormTests()
|
||||
{
|
||||
// Default: empty library (no $ref entries). Individual tests override.
|
||||
@@ -56,6 +57,7 @@ public class ParameterValueFormTests : BunitContext
|
||||
}
|
||||
""";
|
||||
|
||||
/// <summary>Verifies that an object parameter renders one input per field instead of a raw textarea.</summary>
|
||||
[Fact]
|
||||
public void ObjectParameter_RendersPerFieldInputs_NotRawTextarea()
|
||||
{
|
||||
@@ -78,6 +80,7 @@ public class ParameterValueFormTests : BunitContext
|
||||
Assert.Contains("name", cut.Markup);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an object parameter round-trips to the canonical nested JSON shape.</summary>
|
||||
[Fact]
|
||||
public void ObjectParameter_RoundTripsToCanonicalNestedJsonShape()
|
||||
{
|
||||
@@ -101,6 +104,7 @@ public class ParameterValueFormTests : BunitContext
|
||||
Assert.Equal("widget", order["name"]);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a list parameter renders typed item rows with add and remove controls.</summary>
|
||||
[Fact]
|
||||
public void ListParameter_RendersAddRemoveTypedItemRows()
|
||||
{
|
||||
@@ -131,6 +135,7 @@ public class ParameterValueFormTests : BunitContext
|
||||
Assert.Empty(tagsAfter);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a parameter containing a reference renders the resolved shape.</summary>
|
||||
[Fact]
|
||||
public void RefBearingParameter_RendersResolvedShape()
|
||||
{
|
||||
@@ -169,6 +174,7 @@ public class ParameterValueFormTests : BunitContext
|
||||
Assert.Equal(2, cut.FindAll("input[type=text]").Count);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a per-field validation error is shown inline.</summary>
|
||||
[Fact]
|
||||
public void PerFieldValidationError_SurfacesInline()
|
||||
{
|
||||
@@ -185,7 +191,8 @@ public class ParameterValueFormTests : BunitContext
|
||||
Assert.NotEmpty(cut.FindAll(".text-danger"));
|
||||
}
|
||||
|
||||
// M1 — top-level $ref: empty-state guard must key off resolved fields, not _shapes
|
||||
// Top-level $ref: empty-state guard must key off resolved fields, not _shapes
|
||||
/// <summary>Verifies that a top-level reference resolving to an object renders its fields rather than an empty state.</summary>
|
||||
[Fact]
|
||||
public void TopLevelRef_ResolvesToObject_RendersFields_NotEmptyState()
|
||||
{
|
||||
@@ -228,6 +235,7 @@ public class ParameterValueFormTests : BunitContext
|
||||
// is cleared on invalid input, not the containing dict). This is the scenario the
|
||||
// ShiftDict fix is designed for: "rows[1].qty" → "rows[0].qty" when rows[0] is
|
||||
// removed, so the error/raw-text follows the item rather than being wiped.
|
||||
/// <summary>Verifies that removing a list item shifts the nested raw text of later items instead of wiping it.</summary>
|
||||
[Fact]
|
||||
public void ListItemRemoval_ShiftsNestedRawTextOfLaterItems_NotWiped()
|
||||
{
|
||||
@@ -283,6 +291,7 @@ public class ParameterValueFormTests : BunitContext
|
||||
Assert.NotEmpty(cut.FindAll(".text-danger"));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the valid-changed callback reports false on a parse error and true once it is fixed.</summary>
|
||||
[Fact]
|
||||
public void ValidChanged_ReportsFalseOnAParseError_AndTrueOnceFixed()
|
||||
{
|
||||
@@ -298,6 +307,7 @@ public class ParameterValueFormTests : BunitContext
|
||||
Assert.True(valid.Last());
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the valid-changed callback reports false on first render when a required field is empty.</summary>
|
||||
[Fact]
|
||||
public void ValidChanged_ReportsFalseOnFirstRender_WhenARequiredFieldIsEmpty()
|
||||
{
|
||||
@@ -315,6 +325,7 @@ public class ParameterValueFormTests : BunitContext
|
||||
Assert.Empty(cut.FindAll(".text-danger"));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the valid-changed callback reports true on first render when nothing is required.</summary>
|
||||
[Fact]
|
||||
public void ValidChanged_ReportsTrueOnFirstRender_WhenNothingIsRequired()
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ using SchemaLibraryPage = ZB.MOM.WW.ScadaBridge.CentralUI.Components.Pages.Desig
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
|
||||
/// <summary>
|
||||
/// bUnit tests for the Schema Library page (M9-T32c). The page lists the reusable named
|
||||
/// bUnit tests for the Schema Library page. The page lists the reusable named
|
||||
/// JSON-Schema library entries, authors create/edit via the shared <c>SchemaBuilder</c>
|
||||
/// component, and deletes with a confirm — every mutation dispatched through
|
||||
/// <see cref="ISchemaLibraryService"/> (the guard-running ManagementActor path), never a
|
||||
@@ -23,6 +23,7 @@ public class SchemaLibraryPageTests : BunitContext
|
||||
{
|
||||
private readonly ISchemaLibraryService _service = Substitute.For<ISchemaLibraryService>();
|
||||
|
||||
/// <summary>Initializes the test context with a substituted schema library service and an auto-confirming dialog service.</summary>
|
||||
public SchemaLibraryPageTests()
|
||||
{
|
||||
Services.AddSingleton(_service);
|
||||
@@ -51,6 +52,7 @@ public class SchemaLibraryPageTests : BunitContext
|
||||
_service.ListAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<SharedSchema>>(schemas.ToList()));
|
||||
|
||||
/// <summary>Verifies that the page renders the empty state when there are no schemas.</summary>
|
||||
[Fact]
|
||||
public void Renders_EmptyState_WhenNoSchemas()
|
||||
{
|
||||
@@ -60,6 +62,7 @@ public class SchemaLibraryPageTests : BunitContext
|
||||
Assert.Contains("No library schemas defined", cut.Markup));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that existing schemas are listed together with their library reference.</summary>
|
||||
[Fact]
|
||||
public void Lists_ExistingSchemas_WithLibReference()
|
||||
{
|
||||
@@ -78,6 +81,7 @@ public class SchemaLibraryPageTests : BunitContext
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Verifies that choosing New Schema opens the editor with the schema builder.</summary>
|
||||
[Fact]
|
||||
public void NewSchema_OpensEditor_WithSchemaBuilder()
|
||||
{
|
||||
@@ -92,6 +96,7 @@ public class SchemaLibraryPageTests : BunitContext
|
||||
Assert.NotNull(cut.FindComponent<SchemaBuilder>());
|
||||
}
|
||||
|
||||
/// <summary>Verifies that creating a schema dispatches a create command carrying the name and schema.</summary>
|
||||
[Fact]
|
||||
public void Create_DispatchesCreateCommand_WithNameAndSchema()
|
||||
{
|
||||
@@ -112,6 +117,7 @@ public class SchemaLibraryPageTests : BunitContext
|
||||
"Address", Arg.Any<string?>(), Arg.Any<string>(), Arg.Any<CancellationToken>()));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a guard error from a create is shown inline and the editor stays open.</summary>
|
||||
[Fact]
|
||||
public void Create_GuardError_IsShownInline_AndEditorStaysOpen()
|
||||
{
|
||||
@@ -133,6 +139,7 @@ public class SchemaLibraryPageTests : BunitContext
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Verifies that saving with an empty name dispatches no command.</summary>
|
||||
[Fact]
|
||||
public void EmptyName_DoesNotDispatch()
|
||||
{
|
||||
@@ -148,6 +155,7 @@ public class SchemaLibraryPageTests : BunitContext
|
||||
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<string>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
/// <summary>Verifies that deleting a schema confirms first, dispatches a delete command and reloads the list.</summary>
|
||||
[Fact]
|
||||
public void Delete_ConfirmsThenDispatchesDeleteCommand_AndReloads()
|
||||
{
|
||||
@@ -168,6 +176,7 @@ public class SchemaLibraryPageTests : BunitContext
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Verifies that editing a schema opens the editor and dispatches an update command.</summary>
|
||||
[Fact]
|
||||
public void Edit_OpensEditor_AndDispatchesUpdateCommand()
|
||||
{
|
||||
@@ -188,10 +197,11 @@ public class SchemaLibraryPageTests : BunitContext
|
||||
9, "Address", Arg.Any<string?>(), Arg.Any<string>(), Arg.Any<CancellationToken>()));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that row actions are disabled while the editor is open so the row under edit cannot be deleted.</summary>
|
||||
[Fact]
|
||||
public void Editing_DisablesRowActions_SoTheRowUnderEditCannotBeDeleted()
|
||||
{
|
||||
// #260: while the edit form is open the list still shows the row, but its
|
||||
// While the edit form is open the list still shows the row, but its
|
||||
// Edit/Delete actions must be disabled so the row under edit (or a sibling)
|
||||
// can't be deleted out from under the form.
|
||||
SeedSchemas(new SharedSchema { Id = 9, Name = "Address", Scope = "us", SchemaJson = "{\"type\":\"object\"}" });
|
||||
@@ -211,19 +221,28 @@ public class SchemaLibraryPageTests : BunitContext
|
||||
/// <summary>A dialog service that auto-confirms, so the delete path runs end-to-end.</summary>
|
||||
private sealed class AlwaysConfirmDialogService : IDialogService
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task<bool> ConfirmAsync(string title, string message, bool danger = false, string? confirmLabel = null)
|
||||
=> Task.FromResult(true);
|
||||
|
||||
// Register row 75 added a DialogSeverity overload. This stub auto-confirms
|
||||
// regardless of severity — it exists to let action paths run end to end, not to
|
||||
// assert anything about styling.
|
||||
/// <inheritdoc />
|
||||
public Task<bool> ConfirmAsync(string title, string message, DialogSeverity severity, string? confirmLabel = null)
|
||||
=> Task.FromResult(true);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<string?> PromptAsync(
|
||||
string title, string label, string initialValue = "", string? placeholder = null)
|
||||
=> Task.FromResult<string?>(null);
|
||||
|
||||
/// <summary>Returns the default result without showing a dialog.</summary>
|
||||
/// <typeparam name="TResult">The type of result the dialog would produce.</typeparam>
|
||||
/// <param name="title">The dialog title.</param>
|
||||
/// <param name="body">The dialog body fragment.</param>
|
||||
/// <param name="size">The optional dialog size.</param>
|
||||
/// <returns>A task whose result is the default value of <typeparamref name="TResult"/>.</returns>
|
||||
public Task<TResult?> ShowAsync<TResult>(
|
||||
string title,
|
||||
Microsoft.AspNetCore.Components.RenderFragment<DialogContext<TResult>> body,
|
||||
|
||||
+11
-1
@@ -7,7 +7,7 @@ using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for the schema-library read-accessor (M9-T32c) that T30's schema-driven
|
||||
/// Tests for the schema-library read-accessor that the schema-driven
|
||||
/// value-entry forms reuse to resolve <c>{"$ref":"lib:Name"}</c> pointers. It projects
|
||||
/// <see cref="ISharedSchemaRepository"/> onto a name → schema-JSON map (and a single-name
|
||||
/// lookup) over a fresh DI scope. The repository is substituted and registered scoped so
|
||||
@@ -25,6 +25,8 @@ public class SchemaLibraryQueryServiceTests
|
||||
return (service, repo);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the schema map associates each library name with its schema JSON.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task GetSchemaMapAsync_MapsNameToSchemaJson()
|
||||
{
|
||||
@@ -42,6 +44,8 @@ public class SchemaLibraryQueryServiceTests
|
||||
Assert.Equal("{\"type\":\"array\"}", map["GeoPoint"]);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an empty library yields an empty schema map.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task GetSchemaMapAsync_EmptyLibrary_ReturnsEmptyMap()
|
||||
{
|
||||
@@ -53,6 +57,8 @@ public class SchemaLibraryQueryServiceTests
|
||||
Assert.Empty(map);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that resolving a known name returns its schema JSON.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task ResolveAsync_KnownName_ReturnsSchemaJson()
|
||||
{
|
||||
@@ -65,6 +71,8 @@ public class SchemaLibraryQueryServiceTests
|
||||
Assert.Equal("{\"type\":\"object\"}", json);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that resolving an unknown name returns null.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task ResolveAsync_UnknownName_ReturnsNull()
|
||||
{
|
||||
@@ -74,6 +82,8 @@ public class SchemaLibraryQueryServiceTests
|
||||
Assert.Null(await service.ResolveAsync("Missing"));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that resolving an empty name returns null without querying the repository.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task ResolveAsync_EmptyName_ReturnsNull_WithoutHittingRepo()
|
||||
{
|
||||
|
||||
+13
-2
@@ -17,7 +17,7 @@ using SharedScriptFormPage = ZB.MOM.WW.ScadaBridge.CentralUI.Components.Pages.De
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
|
||||
/// <summary>
|
||||
/// Regression tests for arch-review P6-12. <c>ApiMethodForm</c> and
|
||||
/// Regression tests for the sandbox-run cancellation defect. <c>ApiMethodForm</c> and
|
||||
/// <c>SharedScriptForm</c> run a Test Run sandbox script via
|
||||
/// <c>AnalysisService.RunInSandboxAsync(request, _runCts.Token)</c> but — unlike
|
||||
/// <c>TemplateScriptDialog</c>, which cancels/disposes <c>_runCts</c> from an
|
||||
@@ -36,7 +36,7 @@ namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
/// requires <c>ScriptAnalysisService.RunInSandboxAsync</c> to be <c>virtual</c> —
|
||||
/// a test-only seam added alongside this fix (mirroring the pre-existing
|
||||
/// <c>virtual</c> on <c>DebugStreamService.StartStreamAsync</c>/<c>StopStream</c>),
|
||||
/// not itself part of the P6-12 defect or its fix.
|
||||
/// not itself part of the defect or its fix.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Proof of failure:</b> stashing only the two <c>.razor</c> changes (leaving
|
||||
@@ -51,6 +51,7 @@ namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
/// </summary>
|
||||
public class ApiMethodFormSandboxDisposalTests : BunitContext
|
||||
{
|
||||
/// <summary>Initializes a new instance of <c>GatedScriptAnalysisService</c>.</summary>
|
||||
private (IRenderedComponent<ApiMethodFormPage> Cut, GatedScriptAnalysisService Sandbox) RenderPage()
|
||||
{
|
||||
// ApiMethodForm mounts a MonacoEditor unconditionally; let bUnit answer its
|
||||
@@ -99,6 +100,8 @@ public class ApiMethodFormSandboxDisposalTests : BunitContext
|
||||
typeof(ApiMethodFormPage).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic)!
|
||||
.GetValue(page);
|
||||
|
||||
/// <summary>Verifies that dispose mid run cancels the sandbox run token.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Dispose_MidRun_CancelsTheSandboxRunToken()
|
||||
{
|
||||
@@ -124,6 +127,8 @@ public class ApiMethodFormSandboxDisposalTests : BunitContext
|
||||
await run.WaitAsync(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that dispose mid run continuation is a no op.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Dispose_MidRun_ContinuationIsANoOp()
|
||||
{
|
||||
@@ -198,6 +203,8 @@ public class SharedScriptFormSandboxDisposalTests : BunitContext
|
||||
typeof(SharedScriptFormPage).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic)!
|
||||
.GetValue(page);
|
||||
|
||||
/// <summary>Verifies that dispose mid run cancels the sandbox run token.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Dispose_MidRun_CancelsTheSandboxRunToken()
|
||||
{
|
||||
@@ -220,6 +227,8 @@ public class SharedScriptFormSandboxDisposalTests : BunitContext
|
||||
await run.WaitAsync(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that dispose mid run continuation is a no op.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Dispose_MidRun_ContinuationIsANoOp()
|
||||
{
|
||||
@@ -260,6 +269,7 @@ internal sealed class GatedScriptAnalysisService : ScriptAnalysisService
|
||||
private readonly TaskCompletionSource _entered =
|
||||
new(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
/// <summary>Initializes a new instance of <c>GatedScriptAnalysisService</c>.</summary>
|
||||
public GatedScriptAnalysisService()
|
||||
: base(
|
||||
Substitute.For<ISharedScriptCatalog>(),
|
||||
@@ -278,6 +288,7 @@ internal sealed class GatedScriptAnalysisService : ScriptAnalysisService
|
||||
public void ReleaseRun() => _gate.TrySetResult(
|
||||
new SandboxRunResult(true, "1", "int", "", null, SandboxErrorKind.None, 1, null));
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task<SandboxRunResult> RunInSandboxAsync(SandboxRunRequest request, CancellationToken ct)
|
||||
{
|
||||
LastToken = ct;
|
||||
|
||||
+4
@@ -30,6 +30,7 @@ public class TemplateAlarmDialogMesReportableTests
|
||||
private static string TemplateEditMarkup
|
||||
=> File.ReadAllText(Path.Combine(DesignComponentsRoot, "TemplateEdit.razor"));
|
||||
|
||||
/// <summary>Verifies that the alarm dialog has a MES-reportable checkbox.</summary>
|
||||
[Fact]
|
||||
public void AlarmDialog_HasMesReportableCheckbox()
|
||||
{
|
||||
@@ -39,6 +40,7 @@ public class TemplateAlarmDialogMesReportableTests
|
||||
Assert.Contains("MES reportable", markup);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the alarm dialog threads the MES-reportable flag through its parameter and draft.</summary>
|
||||
[Fact]
|
||||
public void AlarmDialog_ThreadsMesReportableThroughParameterAndDraft()
|
||||
{
|
||||
@@ -48,6 +50,7 @@ public class TemplateAlarmDialogMesReportableTests
|
||||
Assert.Contains("bool IsMesReportable", markup);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the alarms tab has a MES column.</summary>
|
||||
[Fact]
|
||||
public void AlarmsTab_HasMesColumn()
|
||||
{
|
||||
@@ -57,6 +60,7 @@ public class TemplateAlarmDialogMesReportableTests
|
||||
Assert.Contains("alarm.IsMesReportable", markup);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the alarms tab passes the MES-reportable flag into and out of the dialog.</summary>
|
||||
[Fact]
|
||||
public void AlarmsTab_PassesMesReportableIntoAndOutOfTheDialog()
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@ using TemplateEditPage = ZB.MOM.WW.ScadaBridge.CentralUI.Components.Pages.Design
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
|
||||
/// <summary>
|
||||
/// bUnit tests for the template editor's READ-ONLY inheritance preview (M9-T26b):
|
||||
/// bUnit tests for the template editor's READ-ONLY inheritance preview:
|
||||
/// rendering the FULL transitively-resolved inherited member set (not just the
|
||||
/// immediate base) annotated with origin, plus a read-only base-changed staleness
|
||||
/// banner. The resolve query is dispatched through
|
||||
@@ -41,6 +41,7 @@ public class TemplateEditInheritedSetTests : BunitContext
|
||||
private const int DerivedId = 30;
|
||||
private const int BaseId = 20;
|
||||
|
||||
/// <summary>Initializes the bUnit context and registers the fakes and services the template editor needs.</summary>
|
||||
public TemplateEditInheritedSetTests()
|
||||
{
|
||||
Services.AddSingleton(_repo);
|
||||
@@ -121,6 +122,7 @@ public class TemplateEditInheritedSetTests : BunitContext
|
||||
_resolve.ResolveAsync(DerivedId, Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<ResolvedTemplateMembers?>(resolved));
|
||||
|
||||
/// <summary>Verifies that transitively inherited members are rendered with an origin annotation.</summary>
|
||||
[Fact]
|
||||
public void Renders_TransitivelyInheritedMembers_WithOriginAnnotation()
|
||||
{
|
||||
@@ -167,6 +169,7 @@ public class TemplateEditInheritedSetTests : BunitContext
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the effective alarm trigger configuration is rendered from the resolved set.</summary>
|
||||
[Fact]
|
||||
public void Renders_EffectiveAlarmTriggerConfiguration_FromResolvedSet()
|
||||
{
|
||||
@@ -203,6 +206,7 @@ public class TemplateEditInheritedSetTests : BunitContext
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the staleness banner is shown when the resolved set is stale.</summary>
|
||||
[Fact]
|
||||
public void Shows_StalenessBanner_WhenResolvedSetIsStale()
|
||||
{
|
||||
@@ -235,6 +239,7 @@ public class TemplateEditInheritedSetTests : BunitContext
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Verifies that no staleness banner is shown when the resolved set is not stale.</summary>
|
||||
[Fact]
|
||||
public void NoStalenessBanner_WhenResolvedSetIsNotStale()
|
||||
{
|
||||
|
||||
+7
-3
@@ -1,7 +1,7 @@
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
|
||||
/// <summary>
|
||||
/// Task 24: the template editor exposes a Native Alarm Sources subsection (a new
|
||||
/// The template editor exposes a Native Alarm Sources subsection (a new
|
||||
/// tab) for authoring read-only native alarm bindings. <c>TemplateEdit</c> is a
|
||||
/// heavyweight page (~10 injected services with their own graphs); like the other
|
||||
/// TemplateEdit coverage in this suite (see <c>TestRunWarningTests</c>), these are
|
||||
@@ -28,13 +28,14 @@ public class TemplateNativeAlarmSourceEditorTests
|
||||
private static string TemplateEditMarkup
|
||||
=> File.ReadAllText(Path.Combine(DesignComponentsRoot, "TemplateEdit.razor"));
|
||||
|
||||
// M10 residual: the authoring form moved out of the page into the dialog body
|
||||
// The authoring form moved out of the page into the dialog body
|
||||
// component hosted by IDialogService.ShowAsync. The field-level assertions
|
||||
// below follow it there; the tab, the connection filtering, and the CRUD
|
||||
// wiring all still live on the page.
|
||||
private static string NativeSourceDialogMarkup
|
||||
=> File.ReadAllText(Path.Combine(DesignComponentsRoot, "TemplateNativeAlarmSourceDialog.razor"));
|
||||
|
||||
/// <summary>Verifies that the template editor has a Native Alarms tab.</summary>
|
||||
[Fact]
|
||||
public void TemplateEditor_HasNativeAlarmsTab()
|
||||
{
|
||||
@@ -45,6 +46,7 @@ public class TemplateNativeAlarmSourceEditorTests
|
||||
Assert.Contains("Native Alarm Sources", markup);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the native alarms form has connection, source filter and lock fields.</summary>
|
||||
[Fact]
|
||||
public void NativeAlarmsForm_HasConnectionSourceFilterAndLockFields()
|
||||
{
|
||||
@@ -67,10 +69,11 @@ public class TemplateNativeAlarmSourceEditorTests
|
||||
Assert.Contains("@bind=\"_nasIsLocked\"", dialogMarkup);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the native alarms form is hosted by the dialog service rather than embedded in the page.</summary>
|
||||
[Fact]
|
||||
public void NativeAlarmsForm_IsHostedByTheDialogService()
|
||||
{
|
||||
// M10 residual: the page-embedded modal is gone — the form opens through
|
||||
// The page-embedded modal is gone — the form opens through
|
||||
// IDialogService.ShowAsync so the host owns the backdrop, focus trap,
|
||||
// Escape, and focus restoration.
|
||||
var pageMarkup = TemplateEditMarkup;
|
||||
@@ -83,6 +86,7 @@ public class TemplateNativeAlarmSourceEditorTests
|
||||
Assert.Contains("DialogContext<bool> Context", dialogMarkup);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that native alarm add, update and delete are wired to the repository followed by a save.</summary>
|
||||
[Fact]
|
||||
public void NativeAlarmsCrud_WiresRepositoryAddUpdateDeleteWithSave()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
|
||||
|
||||
/// <summary>
|
||||
/// Regression tests for CentralUI-014. Test Run wires <c>External</c>,
|
||||
/// Regression tests for the Test Run side-effect warning. Test Run wires <c>External</c>,
|
||||
/// <c>Database</c>, and <c>Notify</c> to central's real services, so a Test Run
|
||||
/// has production-equivalent side effects. The finding asked, at minimum, that
|
||||
/// this blast radius be surfaced to the user. The Test Run panels in
|
||||
@@ -29,9 +29,11 @@ public class TestRunWarningTests
|
||||
private static string Read(string fileName)
|
||||
=> File.ReadAllText(Path.Combine(SrcRoot, fileName));
|
||||
|
||||
// M10 residual: the template Test Run panel moved out of TemplateEdit.razor
|
||||
// The template Test Run panel moved out of TemplateEdit.razor
|
||||
// into TemplateScriptDialog.razor when the page-embedded script modal was
|
||||
// migrated to the IDialogService host. The warning travelled with it.
|
||||
/// <summary>Verifies that a Test Run panel with a real I/O surface shows the real I/O badge and warning.</summary>
|
||||
/// <param name="razorFile">The Razor file containing the Test Run panel.</param>
|
||||
[Theory]
|
||||
[InlineData("SharedScriptForm.razor")]
|
||||
[InlineData("TemplateScriptDialog.razor")]
|
||||
@@ -47,6 +49,7 @@ public class TestRunWarningTests
|
||||
Assert.Contains("Side effects are permanent", markup);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the API method form Test Run shows no real I/O badge because the inbound API has no side-effect surface.</summary>
|
||||
[Fact]
|
||||
public void ApiMethodForm_TestRun_HasNoRealIoBadge_BecauseInboundApiHasNoSideEffectSurface()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user