diff --git a/tests/ZB.MOM.WW.ScadaBridge.Transport.IntegrationTests/Import/NativeAlarmSourceImportTests.cs b/tests/ZB.MOM.WW.ScadaBridge.Transport.IntegrationTests/Import/NativeAlarmSourceImportTests.cs index 2d6b9600..6c1a77ac 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.Transport.IntegrationTests/Import/NativeAlarmSourceImportTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.Transport.IntegrationTests/Import/NativeAlarmSourceImportTests.cs @@ -103,15 +103,17 @@ public sealed class NativeAlarmSourceImportTests : IDisposable string connection = "OpcUaPrimary", string sourceRef = "ns=3;s=Boiler.Alarm", string? filter = "severity>500", - bool locked = false) => new(name) + bool locked = false, + bool inherited = false, + bool lockedInDerived = false) => new(name) { Description = "boiler native alarms", ConnectionName = connection, SourceReference = sourceRef, ConditionFilter = filter, IsLocked = locked, - IsInherited = false, - LockedInDerived = false, + IsInherited = inherited, + LockedInDerived = lockedInDerived, }; [Fact] @@ -121,7 +123,8 @@ public sealed class NativeAlarmSourceImportTests : IDisposable { var ctx = scope.ServiceProvider.GetRequiredService(); var t = new Template("Pump") { Description = "tpl" }; - t.NativeAlarmSources.Add(MakeSource(locked: true)); + // Set every flag non-default so BuildTemplate's fidelity is exercised. + t.NativeAlarmSources.Add(MakeSource(locked: true, inherited: true, lockedInDerived: true)); ctx.Templates.Add(t); await ctx.SaveChangesAsync(); } @@ -155,6 +158,39 @@ public sealed class NativeAlarmSourceImportTests : IDisposable Assert.Equal("ns=3;s=Boiler.Alarm", src.SourceReference); Assert.Equal("severity>500", src.ConditionFilter); Assert.True(src.IsLocked); + Assert.True(src.IsInherited); + Assert.True(src.LockedInDerived); + } + } + + [Fact] + public async Task Import_Overwrite_NoChange_EmitsNoNativeSourceAudit() + { + // An idempotent Overwrite (bundle == target) must produce ZERO + // TemplateNativeAlarmSource* audit rows — the "no audit noise" invariant. + await using (var scope = _provider.CreateAsyncScope()) + { + var ctx = scope.ServiceProvider.GetRequiredService(); + var t = new Template("Pump") { Description = "same" }; + t.NativeAlarmSources.Add(MakeSource("Boiler", locked: true, lockedInDerived: true)); + ctx.Templates.Add(t); + await ctx.SaveChangesAsync(); + } + var sessionId = await ExportAllTemplatesAndLoadAsync(); + + await using (var scope = _provider.CreateAsyncScope()) + { + var importer = scope.ServiceProvider.GetRequiredService(); + await importer.ApplyAsync(sessionId, + new List { new("Template", "Pump", ResolutionAction.Overwrite, null) }, + user: "bob"); + } + + await using (var scope = _provider.CreateAsyncScope()) + { + var ctx = scope.ServiceProvider.GetRequiredService(); + Assert.False(await ctx.AuditLogEntries.AnyAsync(a => + a.Action.StartsWith("TemplateNativeAlarmSource"))); } } diff --git a/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Serialization/EntitySerializerTests.cs b/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Serialization/EntitySerializerTests.cs index 57c5eda8..1846aab7 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Serialization/EntitySerializerTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Serialization/EntitySerializerTests.cs @@ -215,7 +215,7 @@ public sealed class EntitySerializerTests SourceReference = "ns=3;s=Boiler.Alarm", ConditionFilter = "severity>500", IsLocked = true, - IsInherited = false, + IsInherited = true, LockedInDerived = true, }); @@ -230,6 +230,7 @@ public sealed class EntitySerializerTests Assert.Equal("ns=3;s=Boiler.Alarm", dtoSrc.SourceReference); Assert.Equal("severity>500", dtoSrc.ConditionFilter); Assert.True(dtoSrc.IsLocked); + Assert.True(dtoSrc.IsInherited); Assert.True(dtoSrc.LockedInDerived); var rtSrc = Assert.Single(Assert.Single(sut.FromBundleContent(dto).Templates).NativeAlarmSources); @@ -239,6 +240,7 @@ public sealed class EntitySerializerTests Assert.Equal("ns=3;s=Boiler.Alarm", rtSrc.SourceReference); Assert.Equal("severity>500", rtSrc.ConditionFilter); Assert.True(rtSrc.IsLocked); + Assert.True(rtSrc.IsInherited); Assert.True(rtSrc.LockedInDerived); }