feat(scripts): ScriptAlarm.IsMesReportable + Alarms.MesReportableAsync() mirrored on both compile surfaces

Claude-Session: https://claude.ai/code/session_01Y5ef34iUUMjmwnMpL9xgmB
This commit is contained in:
Joseph Doherty
2026-09-11 10:12:47 -04:00
parent ce8fc092c8
commit 17d9a4cd2c
8 changed files with 92 additions and 4 deletions
@@ -187,6 +187,43 @@ public class AlarmsAccessorTests : TestKit, IDisposable
Assert.Equal("Z28061.HeartbeatTimeoutAlarm", real.Name);
}
[Fact]
public async Task CurrentAsync_ProjectsIsMesReportable()
{
// The deployed configuration's MES-reportable flag rides the snapshot row and must
// reach the script projection verbatim — a row without it reads false.
var probe = CreateTestProbe();
var ctx = MakeContext(probe.Ref);
var pending = ctx.Alarms.CurrentAsync();
RespondWith(probe,
NativeAcked() with { IsMesReportable = true },
new AlarmStateChanged("CvdReactor01", "HighTemp", AlarmState.Active, 700, ObservedAt));
var alarms = await pending;
Assert.Equal(2, alarms.Count);
Assert.True(Assert.Single(alarms, a => a.Name == "Z28061.HeartbeatTimeoutAlarm").IsMesReportable);
Assert.False(Assert.Single(alarms, a => a.Name == "HighTemp").IsMesReportable);
}
[Fact]
public async Task MesReportableAsync_FiltersToFlaggedRows()
{
// The convenience accessor is CurrentAsync restricted to the flagged subset, so a
// script does not have to repeat the filter (and cannot get it subtly wrong).
var probe = CreateTestProbe();
var ctx = MakeContext(probe.Ref);
var pending = ctx.Alarms.MesReportableAsync();
RespondWith(probe,
NativeAcked() with { IsMesReportable = true },
NativeAcked() with { AlarmName = "Z28061.UnflaggedAlarm", SourceReference = "Z28061.UnflaggedAlarm" });
var alarm = Assert.Single(await pending);
Assert.Equal("Z28061.HeartbeatTimeoutAlarm", alarm.Name);
Assert.True(alarm.IsMesReportable);
}
[Fact]
public async Task CurrentAsync_IsNotScopePrefixed_EveryScopeSeesTheSameList()
{