fix(management): case-variant instance override names are rejected with a did-you-mean hint (ScadaBridge#105)
Verified the ManagementActor bulk attribute override and single/bulk native alarm source override paths match names ordinally and already reject a case-variant name (nothing stored); the error now names the single case-insensitive match. Tests pin the rejection. Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
@@ -2811,6 +2811,58 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
// command up front WITHOUT persisting any of the overrides.
|
||||
// ========================================================================
|
||||
|
||||
/// <summary>ScadaBridge#105: a bulk attribute override differing from the member only by case is rejected with a hint, nothing stored.</summary>
|
||||
[Fact]
|
||||
public void SetInstanceOverrides_CaseVariantName_IsRejectedWithHint_PersistsNothing()
|
||||
{
|
||||
var instance = new Instance("Pump5") { Id = 5, SiteId = 1, TemplateId = 1 };
|
||||
_templateRepo.GetInstanceByIdAsync(5, Arg.Any<CancellationToken>()).Returns(instance);
|
||||
_templateRepo.GetAttributesByTemplateIdAsync(1, Arg.Any<CancellationToken>())
|
||||
.Returns(new List<TemplateAttribute> { new("Setpoint") { Id = 1, TemplateId = 1 } });
|
||||
_templateRepo.GetOverridesByInstanceIdAsync(5, Arg.Any<CancellationToken>())
|
||||
.Returns(new List<Commons.Entities.Instances.InstanceAttributeOverride>());
|
||||
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new SetInstanceOverridesCommand(5, new Dictionary<string, string?> { ["setpoint"] = "1" }), "Deployer"));
|
||||
|
||||
var response = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
||||
Assert.Equal("COMMAND_FAILED", response.ErrorCode);
|
||||
Assert.Contains("did you mean 'Setpoint'", response.Error);
|
||||
_templateRepo.DidNotReceiveWithAnyArgs().AddInstanceAttributeOverrideAsync(default!, default);
|
||||
}
|
||||
|
||||
/// <summary>ScadaBridge#105: a bulk native-source override differing only by case is rejected, nothing stored.</summary>
|
||||
[Fact]
|
||||
public void SetInstanceNativeAlarmSourceOverrides_CaseVariantName_IsRejectedWithHint()
|
||||
{
|
||||
StubFlattenedNativeSources("Pressure");
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(
|
||||
new SetInstanceNativeAlarmSourceOverridesCommand(1, new List<NativeAlarmSourceOverrideEntry>
|
||||
{
|
||||
new("pressure", "Opc2", null, null)
|
||||
}),
|
||||
"Deployer"));
|
||||
|
||||
var response = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("did you mean 'Pressure'", response.Error);
|
||||
_templateRepo.DidNotReceiveWithAnyArgs().AddInstanceNativeAlarmSourceOverrideAsync(default!, default);
|
||||
}
|
||||
|
||||
/// <summary>ScadaBridge#105: a single native-source override differing only by case is rejected, nothing stored.</summary>
|
||||
[Fact]
|
||||
public void SetInstanceNativeAlarmSourceOverride_CaseVariantName_IsRejectedWithHint()
|
||||
{
|
||||
StubFlattenedNativeSources("Pressure");
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(
|
||||
new SetInstanceNativeAlarmSourceOverrideCommand(1, "PRESSURE", "Opc2", null, null), "Deployer"));
|
||||
|
||||
var response = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("did you mean 'Pressure'", response.Error);
|
||||
_templateRepo.DidNotReceiveWithAnyArgs().AddInstanceNativeAlarmSourceOverrideAsync(default!, default);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that set instance overrides, when with one invalid attribute, persists no overrides.</summary>
|
||||
[Fact]
|
||||
public void SetInstanceOverrides_WithOneInvalidAttribute_PersistsNoOverrides()
|
||||
|
||||
Reference in New Issue
Block a user