diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceVirtualTagTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceVirtualTagTests.cs index d7fafe1c..dfb2399e 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceVirtualTagTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceVirtualTagTests.cs @@ -163,6 +163,24 @@ public sealed class UnsTreeServiceVirtualTagTests result.Error.ShouldBe("A virtual tag named 'computed' already exists on this equipment."); } + /// Creating a virtual tag with no script chosen is blocked. + [Fact] + public async Task CreateVirtualTag_no_script_blocked() + { + var (service, dbName) = Fresh(); + SeedEquipmentAndScript(dbName); + + var input = Input("VTAG-1", "computed", scriptId: "", changeTriggered: true); + var result = await service.CreateVirtualTagAsync("EQ-1", input); + + result.Ok.ShouldBeFalse(); + result.Error.ShouldNotBeNull(); + result.Error.ShouldContain("Pick a script"); + + using var db = UnsTreeTestDb.CreateNamed(dbName); + db.VirtualTags.Any(v => v.VirtualTagId == "VTAG-1").ShouldBeFalse(); + } + // ----- UpdateVirtualTag ----- /// Updating a virtual tag changes its mutable fields and keeps EquipmentId. @@ -211,6 +229,29 @@ public sealed class UnsTreeServiceVirtualTagTests result.Error.ShouldBe("Row no longer exists."); } + /// Renaming a virtual tag to a name already used by another tag on the same equipment is blocked. + [Fact] + public async Task UpdateVirtualTag_duplicate_name_on_equipment_blocked() + { + var (service, dbName) = Fresh(); + SeedEquipmentAndScript(dbName); + await service.CreateVirtualTagAsync("EQ-1", Input("VTAG-A", "vt_a")); + await service.CreateVirtualTagAsync("EQ-1", Input("VTAG-B", "vt_b")); + + byte[] rv; + using (var db = UnsTreeTestDb.CreateNamed(dbName)) + { + rv = db.VirtualTags.Single(v => v.VirtualTagId == "VTAG-A").RowVersion; + } + + var input = Input("VTAG-A", "vt_b"); // try to rename to the name already used by VTAG-B + var result = await service.UpdateVirtualTagAsync("VTAG-A", input, rv); + + result.Ok.ShouldBeFalse(); + result.Error.ShouldNotBeNull(); + result.Error.ShouldContain("already exists on this equipment"); + } + // ----- DeleteVirtualTag ----- /// Deleting a virtual tag removes the row.