using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.AdminUI.Uns; namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Uns; [Trait("Category", "Unit")] public sealed class UnsTreeServiceScriptedAlarmTests { private static UnsTreeService SeededService() { var dbName = $"uns-alarm-{Guid.NewGuid():N}"; UnsTreeTestDb.SeedNamed(dbName); return new UnsTreeService(UnsTreeTestDb.Factory(dbName)); } private static ScriptedAlarmInput Sample(string id = "SA-1") => new(id, "Over-temp", "LimitAlarm", 700, "{TagPath} hot", "SCRIPT-1", HistorizeToAveva: true, Retain: true, Enabled: true); [Fact] public async Task Create_then_list_and_load_roundtrips() { var svc = SeededService(); var create = await svc.CreateScriptedAlarmAsync(UnsTreeTestDb.SeededEquipmentId, Sample()); create.Ok.ShouldBeTrue(); create.CreatedId.ShouldBe("SA-1"); var rows = await svc.LoadAlarmsForEquipmentAsync(UnsTreeTestDb.SeededEquipmentId); rows.Count.ShouldBe(1); rows[0].Name.ShouldBe("Over-temp"); rows[0].Severity.ShouldBe(700); var dto = await svc.LoadScriptedAlarmAsync("SA-1"); dto.ShouldNotBeNull(); dto!.EquipmentId.ShouldBe(UnsTreeTestDb.SeededEquipmentId); dto.HistorizeToAveva.ShouldBeTrue(); dto.RowVersion.ShouldNotBeNull(); } [Fact] public async Task Create_rejects_duplicate_id() { var svc = SeededService(); (await svc.CreateScriptedAlarmAsync(UnsTreeTestDb.SeededEquipmentId, Sample())).Ok.ShouldBeTrue(); var dup = await svc.CreateScriptedAlarmAsync(UnsTreeTestDb.SeededEquipmentId, Sample()); dup.Ok.ShouldBeFalse(); dup.Error.ShouldNotBeNull(); } [Fact] public async Task Update_changes_fields() { var svc = SeededService(); await svc.CreateScriptedAlarmAsync(UnsTreeTestDb.SeededEquipmentId, Sample()); var dto = await svc.LoadScriptedAlarmAsync("SA-1"); var upd = await svc.UpdateScriptedAlarmAsync("SA-1", Sample() with { Name = "Renamed", Severity = 250, HistorizeToAveva = false }, dto!.RowVersion); upd.Ok.ShouldBeTrue(); var after = await svc.LoadScriptedAlarmAsync("SA-1"); after!.Name.ShouldBe("Renamed"); after.Severity.ShouldBe(250); after.HistorizeToAveva.ShouldBeFalse(); } [Fact] public async Task Delete_removes_row() { var svc = SeededService(); await svc.CreateScriptedAlarmAsync(UnsTreeTestDb.SeededEquipmentId, Sample()); var dto = await svc.LoadScriptedAlarmAsync("SA-1"); (await svc.DeleteScriptedAlarmAsync("SA-1", dto!.RowVersion)).Ok.ShouldBeTrue(); (await svc.LoadAlarmsForEquipmentAsync(UnsTreeTestDb.SeededEquipmentId)).ShouldBeEmpty(); } [Fact] public async Task Create_rejects_duplicate_name_on_same_equipment() { var svc = SeededService(); (await svc.CreateScriptedAlarmAsync(UnsTreeTestDb.SeededEquipmentId, Sample("SA-1"))).Ok.ShouldBeTrue(); // Same Name ("Over-temp" from Sample), different id, same equipment → rejected. var dup = await svc.CreateScriptedAlarmAsync(UnsTreeTestDb.SeededEquipmentId, Sample("SA-2")); dup.Ok.ShouldBeFalse(); dup.Error.ShouldNotBeNull(); dup.Error!.ShouldContain("already exists"); } }