87 lines
3.8 KiB
C#
87 lines
3.8 KiB
C#
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Drivers;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Drivers;
|
|
|
|
/// <summary>
|
|
/// lmxopcua#847: a refused driver/device save stacked two copies of the same error box (the live gate box plus
|
|
/// the gate text copied into the save error), and a resubmit left the previous refusal standing.
|
|
/// </summary>
|
|
[Trait("Category", "Unit")]
|
|
public sealed class SaveRefusalNoticesTests
|
|
{
|
|
[Fact]
|
|
public void Nothing_to_show_renders_nothing()
|
|
=> SaveRefusalNotices.Messages(null, " ").ShouldBeEmpty();
|
|
|
|
[Fact]
|
|
public void The_same_refusal_from_gate_and_save_renders_once()
|
|
=> SaveRefusalNotices.Messages("Credential refused.", "Credential refused.").ShouldBe(["Credential refused."]);
|
|
|
|
[Fact]
|
|
public void A_save_error_that_wraps_the_gate_text_renders_once()
|
|
=> SaveRefusalNotices.Messages("Credential refused.", "Save failed: Credential refused.")
|
|
.ShouldBe(["Credential refused."]);
|
|
|
|
[Fact]
|
|
public void Distinct_gate_and_server_errors_both_render_gate_first()
|
|
=> SaveRefusalNotices.Messages("Credential refused.", "Row was modified by someone else.")
|
|
.ShouldBe(["Credential refused.", "Row was modified by someone else."]);
|
|
|
|
[Fact]
|
|
public void A_server_error_alone_renders()
|
|
=> SaveRefusalNotices.Messages(null, "Duplicate name.").ShouldBe(["Duplicate name."]);
|
|
|
|
[Theory]
|
|
[InlineData("DriverConfigModal.razor", "_driverConfigJson")]
|
|
[InlineData("DeviceModal.razor", "_deviceConfigJson")]
|
|
public void Both_modals_render_one_shared_error_area_and_reset_it_on_resubmit_and_edit(string file, string jsonField)
|
|
{
|
|
var src = AdminUiSource.Read("Components", "Shared", "Drivers", file);
|
|
|
|
src.ShouldContain("<SaveRefusalNotice ");
|
|
src.ShouldNotContain("<div class=\"panel notice notice-alert mt-3\">@_saveError</div>");
|
|
// The gate refusal is no longer COPIED into _saveError (the source of the duplicate box).
|
|
src.ShouldNotContain($"_saveError = DriverConfigSaveGate.Validate(_driverType, {jsonField});");
|
|
src.ShouldContain("_saveError = null;\n if (DriverConfigSaveGate.Validate(");
|
|
// An edit clears a stale server refusal.
|
|
src.ShouldContain($"v => {{ {jsonField} = v; _saveError = null; }}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// lmxopcua#847: Test Connect / browse-open refusals were cut down inside an uppercase chip ("SEC…") with the
|
|
/// real reason only in a hover tooltip. Every site now renders the shared <c>RefusalChip</c>, which prints the
|
|
/// full message under a short chip.
|
|
/// </summary>
|
|
[Trait("Category", "Unit")]
|
|
public sealed class RefusalChipWiringTests
|
|
{
|
|
[Theory]
|
|
[InlineData("Drivers/DriverTestConnectButton.razor")]
|
|
[InlineData("Raw/RawBrowseModal.razor")]
|
|
[InlineData("Drivers/Pickers/AbCipAddressPickerBody.razor")]
|
|
[InlineData("Drivers/Pickers/FOCASAddressPickerBody.razor")]
|
|
[InlineData("Drivers/Pickers/GalaxyAddressPickerBody.razor")]
|
|
[InlineData("Drivers/Pickers/OpcUaClientAddressPickerBody.razor")]
|
|
[InlineData("Drivers/Pickers/SqlAddressPickerBody.razor")]
|
|
[InlineData("Drivers/Pickers/TwinCATAddressPickerBody.razor")]
|
|
public void Refusal_sites_render_the_full_message_via_RefusalChip(string relative)
|
|
{
|
|
var src = AdminUiSource.Read(["Components", "Shared", .. relative.Split('/')]);
|
|
src.ShouldContain("<RefusalChip Message=");
|
|
src.ShouldNotContain("TruncatedError()");
|
|
src.ShouldNotContain("<span class=\"chip chip-bad\" title=");
|
|
}
|
|
|
|
[Fact]
|
|
public void RefusalChip_prints_the_message_untruncated_and_wrapping()
|
|
{
|
|
var src = AdminUiSource.Read("Components", "Shared", "Drivers", "RefusalChip.razor");
|
|
src.ShouldContain("text-break");
|
|
src.ShouldContain(">@Message</span>");
|
|
src.ShouldNotContain("Abbreviate");
|
|
}
|
|
}
|