diff --git a/src/PAModel/IR/IRStateHelpers.cs b/src/PAModel/IR/IRStateHelpers.cs index 9b5fc98b..be3c0d1d 100644 --- a/src/PAModel/IR/IRStateHelpers.cs +++ b/src/PAModel/IR/IRStateHelpers.cs @@ -197,15 +197,17 @@ private static void SplitIRAndState(ControlInfoJson.Item control, string topPare entropy.OverridablePropertiesEntry.Add(control.Name, OverridablePropVal); } - // Storing pcf controls template data in entropy + // Store PCF control template data in entropy, per control. // Since this could be different for different controls, even if that appear to follow the same template // Eg:Control Instance 1 -> pcftemplate1 -> DynamicControlDefinitionJson1 // Control Instance 2 -> pcftemplate1 -> DynamicControlDefinitionJson2 + // A copy of the template will also be kept in the template store, in case entropy data is lost. if (IsPCFControl(control.Template)) { entropy.PCFTemplateEntry.Add(control.Name, control.Template); } - else if (templateStore.TryGetTemplate(control.Template.Name, out var templateState)) + + if (templateStore.TryGetTemplate(control.Template.Name, out var templateState)) { if (isComponentDef) { @@ -307,6 +309,8 @@ private static (ControlInfoJson.Item item, int index) CombineIRAndState(BlockNod ControlInfoJson.Template template; CombinedTemplateState templateState; + + // Prefer the specific PCF template for the control, if available. Otherwise, try to fall back to the template store. if (entropy.PCFTemplateEntry.TryGetValue(controlName, out var PCFTemplate)) { template = PCFTemplate; diff --git a/src/PAModelTests/EntropyTests.cs b/src/PAModelTests/EntropyTests.cs index 74893dea..d7e24569 100644 --- a/src/PAModelTests/EntropyTests.cs +++ b/src/PAModelTests/EntropyTests.cs @@ -97,7 +97,7 @@ public void TestGetResourcesJSONIndicesKeyNullException(string filename) // passing null resource in resourcesJson msapp._resourcesJson = new ResourcesJson() { Resources = new ResourceJson[] { null } }; - + TranformResourceJson.PersistOrderingOfResourcesJsonEntries(msapp); } @@ -128,5 +128,31 @@ public void TestAppWithNoPCFControlInstances(string appName) Assert.IsTrue(msapp._entropy.PCFTemplateEntry.Count == 0); } + + // Validate that a PCF control will still resolve its template by falling back to + // the template store if the control's specific template isn't in Entropy. + [DataTestMethod] + [DataRow("PcfTemplates.msapp")] + public void TestPCFControlWillFallBackToControlTemplate(string appName) + { + var root = Path.Combine(Environment.CurrentDirectory, "Apps", appName); + Assert.IsTrue(File.Exists(root)); + + (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); + errors.ThrowOnErrors(); + + Assert.IsTrue(msapp._entropy.PCFTemplateEntry.Count > 0); + + // Clear out the PCF templates in entropy + msapp._entropy.PCFTemplateEntry.Clear(); + Assert.IsTrue(msapp._entropy.PCFTemplateEntry.Count == 0); + + // Repack the app and validate it matches the initial msapp + using (var tempFile = new TempFile()) + { + MsAppSerializer.SaveAsMsApp(msapp, tempFile.FullPath, new ErrorContainer()); + Assert.IsTrue(MsAppTest.Compare(root, tempFile.FullPath, Console.Out)); + } + } } }