fix(template-engine): computed-alarm IsMesReportable in revision hash and diff, true-only (ScadaBridge#102 item 2)
Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
@@ -142,6 +142,7 @@ public class DiffService
|
|||||||
a.Description == b.Description &&
|
a.Description == b.Description &&
|
||||||
a.PriorityLevel == b.PriorityLevel &&
|
a.PriorityLevel == b.PriorityLevel &&
|
||||||
a.IsLocked == b.IsLocked &&
|
a.IsLocked == b.IsLocked &&
|
||||||
|
a.IsMesReportable == b.IsMesReportable &&
|
||||||
a.TriggerType == b.TriggerType &&
|
a.TriggerType == b.TriggerType &&
|
||||||
a.TriggerConfiguration == b.TriggerConfiguration &&
|
a.TriggerConfiguration == b.TriggerConfiguration &&
|
||||||
a.OnTriggerScriptCanonicalName == b.OnTriggerScriptCanonicalName;
|
a.OnTriggerScriptCanonicalName == b.OnTriggerScriptCanonicalName;
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ public class RevisionHashService
|
|||||||
Description = a.Description,
|
Description = a.Description,
|
||||||
PriorityLevel = a.PriorityLevel,
|
PriorityLevel = a.PriorityLevel,
|
||||||
IsLocked = a.IsLocked,
|
IsLocked = a.IsLocked,
|
||||||
|
// true-only (null when false) so existing revision hashes are unchanged.
|
||||||
|
IsMesReportable = a.IsMesReportable ? true : null,
|
||||||
TriggerType = a.TriggerType,
|
TriggerType = a.TriggerType,
|
||||||
TriggerConfiguration = a.TriggerConfiguration,
|
TriggerConfiguration = a.TriggerConfiguration,
|
||||||
OnTriggerScriptCanonicalName = a.OnTriggerScriptCanonicalName
|
OnTriggerScriptCanonicalName = a.OnTriggerScriptCanonicalName
|
||||||
@@ -242,6 +244,11 @@ public class RevisionHashService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsLocked { get; init; }
|
public bool IsLocked { get; init; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// MES-reportable flag; null when false (the serializer drops nulls), so
|
||||||
|
/// pre-existing configurations hash identically.
|
||||||
|
/// </summary>
|
||||||
|
public bool? IsMesReportable { get; init; }
|
||||||
|
/// <summary>
|
||||||
/// The canonical name of the script triggered by this alarm.
|
/// The canonical name of the script triggered by this alarm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? OnTriggerScriptCanonicalName { get; init; }
|
public string? OnTriggerScriptCanonicalName { get; init; }
|
||||||
|
|||||||
@@ -230,6 +230,28 @@ public class DiffServiceTests
|
|||||||
Assert.Equal(DiffChangeType.Changed, diff.AlarmChanges[0].ChangeType);
|
Assert.Equal(DiffChangeType.Changed, diff.AlarmChanges[0].ChangeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Gitea #102: flipping a computed alarm's MES-reportable flag is a diff.</summary>
|
||||||
|
[Fact]
|
||||||
|
public void ComputeDiff_AlarmIsMesReportableChange_DetectedAsChanged()
|
||||||
|
{
|
||||||
|
var oldConfig = new FlattenedConfiguration
|
||||||
|
{
|
||||||
|
InstanceUniqueName = "Instance1",
|
||||||
|
Alarms = [new ResolvedAlarm { CanonicalName = "HighTemp", TriggerType = "RangeViolation" }]
|
||||||
|
};
|
||||||
|
var newConfig = new FlattenedConfiguration
|
||||||
|
{
|
||||||
|
InstanceUniqueName = "Instance1",
|
||||||
|
Alarms = [new ResolvedAlarm { CanonicalName = "HighTemp", TriggerType = "RangeViolation", IsMesReportable = true }]
|
||||||
|
};
|
||||||
|
|
||||||
|
var diff = _sut.ComputeDiff(oldConfig, newConfig);
|
||||||
|
|
||||||
|
Assert.True(diff.HasChanges);
|
||||||
|
Assert.Single(diff.AlarmChanges);
|
||||||
|
Assert.Equal(DiffChangeType.Changed, diff.AlarmChanges[0].ChangeType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Verifies that a native alarm source reference change is detected as changed.</summary>
|
/// <summary>Verifies that a native alarm source reference change is detected as changed.</summary>
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ComputeDiff_NativeAlarmSourceReferenceChange_DetectedAsChanged()
|
public void ComputeDiff_NativeAlarmSourceReferenceChange_DetectedAsChanged()
|
||||||
|
|||||||
+18
@@ -191,6 +191,24 @@ public class RevisionHashServiceTests
|
|||||||
Assert.NotEqual(_sut.ComputeHash(configBefore), _sut.ComputeHash(configAfter));
|
Assert.NotEqual(_sut.ComputeHash(configBefore), _sut.ComputeHash(configAfter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Gitea #102: the computed alarm's MES-reportable flag participates in the hash; false hashes as before the field existed.</summary>
|
||||||
|
[Fact]
|
||||||
|
public void ComputeHash_AlarmIsMesReportableChange_ChangesHash()
|
||||||
|
{
|
||||||
|
var baseAlarm = new ResolvedAlarm { CanonicalName = "HighTemp", TriggerType = "RangeViolation" };
|
||||||
|
var configFalse = new FlattenedConfiguration
|
||||||
|
{
|
||||||
|
InstanceUniqueName = "Instance1", TemplateId = 1, SiteId = 1,
|
||||||
|
Alarms = [baseAlarm]
|
||||||
|
};
|
||||||
|
var configTrue = configFalse with { Alarms = [baseAlarm with { IsMesReportable = true }] };
|
||||||
|
|
||||||
|
Assert.NotEqual(_sut.ComputeHash(configFalse), _sut.ComputeHash(configTrue));
|
||||||
|
// false is omitted from the canonical JSON, so adding the field cannot invalidate stored hashes.
|
||||||
|
Assert.Equal(_sut.ComputeHash(configFalse),
|
||||||
|
_sut.ComputeHash(configFalse with { Alarms = [baseAlarm with { IsMesReportable = false }] }));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Verifies that editing a connection endpoint changes the hash.</summary>
|
/// <summary>Verifies that editing a connection endpoint changes the hash.</summary>
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ComputeHash_ConnectionEndpointEdit_ChangesHash()
|
public void ComputeHash_ConnectionEndpointEdit_ChangesHash()
|
||||||
|
|||||||
Reference in New Issue
Block a user