using ScadaLink.Commons.Entities.Templates; namespace ScadaLink.TemplateEngine.Tests; /// /// Coverage for — the computed /// hierarchical name of a composition-derived template. Derived templates store /// only their contained name (the composition slot's InstanceName); the /// dotted path is resolved on read by walking the OwnerCompositionId chain. /// public class TemplateNamingTests { private static (Dictionary byId, Dictionary compById) BuildGraph(params Template[] templates) { var byId = templates.ToDictionary(t => t.Id); var compById = templates .SelectMany(t => t.Compositions) .ToDictionary(c => c.Id); return (byId, compById); } [Fact] public void QualifiedName_BaseTemplate_IsJustItsName() { var motorController = new Template("Motor Controller") { Id = 4 }; var (byId, compById) = BuildGraph(motorController); Assert.Equal("Motor Controller", TemplateNaming.QualifiedName(motorController, byId, compById)); } [Fact] public void QualifiedName_OneLevelDerived_PrefixesTheOwner() { // Motor Controller composes the Pump template into a slot named "Pump". var motorController = new Template("Motor Controller") { Id = 4 }; motorController.Compositions.Add( new TemplateComposition("Pump") { Id = 1014, TemplateId = 4, ComposedTemplateId = 2018 }); var derivedPump = new Template("Pump") { Id = 2018, IsDerived = true, OwnerCompositionId = 1014 }; var (byId, compById) = BuildGraph(motorController, derivedPump); Assert.Equal("Motor Controller.Pump", TemplateNaming.QualifiedName(derivedPump, byId, compById)); } [Fact] public void QualifiedName_NestedDerived_WalksTheWholeChain() { // Motor Controller -> Pump slot -> TempSensor slot. var motorController = new Template("Motor Controller") { Id = 4 }; motorController.Compositions.Add( new TemplateComposition("Pump") { Id = 1014, TemplateId = 4, ComposedTemplateId = 2018 }); var derivedPump = new Template("Pump") { Id = 2018, IsDerived = true, OwnerCompositionId = 1014 }; derivedPump.Compositions.Add( new TemplateComposition("TempSensor") { Id = 1015, TemplateId = 2018, ComposedTemplateId = 2019 }); var derivedTempSensor = new Template("TempSensor") { Id = 2019, IsDerived = true, OwnerCompositionId = 1015 }; var (byId, compById) = BuildGraph(motorController, derivedPump, derivedTempSensor); Assert.Equal( "Motor Controller.Pump.TempSensor", TemplateNaming.QualifiedName(derivedTempSensor, byId, compById)); } [Fact] public void QualifiedName_DerivedWithMissingOwnerLink_FallsBackToStoredName() { // Defensive: a derived template whose owner composition is not in the // lookup must not throw — it falls back to the stored contained name. var orphan = new Template("TempSensor") { Id = 2019, IsDerived = true, OwnerCompositionId = 9999 }; var (byId, compById) = BuildGraph(orphan); Assert.Equal("TempSensor", TemplateNaming.QualifiedName(orphan, byId, compById)); } }