diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceAreaLineTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceAreaLineTests.cs index e08036a0..1c5f7ab9 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceAreaLineTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceAreaLineTests.cs @@ -135,6 +135,53 @@ public sealed class UnsTreeServiceAreaLineTests verify.UnsAreas.Single(a => a.UnsAreaId == "AREA-X").ClusterId.ShouldBe("MAIN"); } + /// The #122 guard allows the move when the area's driver-bound equipment's driver + /// is already in the target cluster (driverCluster == newClusterId → no orphan). + [Fact] + public async Task UpdateArea_reassign_cluster_allowed_when_driver_is_in_target_cluster() + { + // Seed: AREA-Z in cluster MAIN, a line, equipment bound to DRV-SITE-A whose cluster is + // SITE-A. Reassigning the area to SITE-A must be allowed because the driver is already + // there — the #122 guard's `driverCluster != newClusterId` condition is false. + var (service, dbName) = Fresh(); + + byte[] rv; + using (var db = UnsTreeTestDb.CreateNamed(dbName)) + { + db.UnsAreas.Add(new UnsArea { UnsAreaId = "AREA-Z", ClusterId = "MAIN", Name = "a" }); + db.UnsLines.Add(new UnsLine { UnsLineId = "LINE-Z", UnsAreaId = "AREA-Z", Name = "l" }); + db.DriverInstances.Add(new DriverInstance + { + DriverInstanceId = "DRV-SITE-A", + ClusterId = "SITE-A", + NamespaceId = "NS-1", + Name = "drv", + DriverType = "ModbusTcp", + DriverConfig = "{}", + }); + db.Equipment.Add(new Equipment + { + EquipmentId = "EQ-BOUND-Z", + EquipmentUuid = Guid.NewGuid(), + UnsLineId = "LINE-Z", + Name = "m", + MachineCode = "machine_z", + DriverInstanceId = "DRV-SITE-A", + }); + db.SaveChanges(); + rv = db.UnsAreas.Single(a => a.UnsAreaId == "AREA-Z").RowVersion; + } + + var result = await service.UpdateAreaAsync("AREA-Z", "a", null, "SITE-A", rv); + + result.Ok.ShouldBeTrue(); + result.Error.ShouldBeNull(); + + // Verify the area actually moved to SITE-A via a fresh context. + using var verify = UnsTreeTestDb.CreateNamed(dbName); + verify.UnsAreas.Single(a => a.UnsAreaId == "AREA-Z").ClusterId.ShouldBe("SITE-A"); + } + /// The #122 guard allows the move when the equipment under the area is driver-less /// (DriverInstanceId == null). [Fact]