Fixes more of U4-1140, ensure that only legacy objects are returned from the dynamic stuff in the razor macros. Adds unit test for it.

This commit is contained in:
Shannon Deminick
2012-11-07 03:49:32 +05:00
parent 315e8b27a0
commit b9d53ceac8
8 changed files with 104 additions and 17 deletions

View File

@@ -5,28 +5,29 @@ namespace Umbraco.Core.Dynamics
{
public class DynamicDictionary : DynamicObject
{
readonly Dictionary<string, object> _dictionary;
internal readonly Dictionary<string, object> SourceItems;
public DynamicDictionary(Dictionary<string, object> sourceItems)
{
_dictionary = sourceItems;
SourceItems = sourceItems;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (_dictionary.ContainsKey(binder.Name))
if (SourceItems.ContainsKey(binder.Name))
{
_dictionary[binder.Name.ToLower()] = value;
SourceItems[binder.Name.ToLower()] = value;
}
else
{
_dictionary.Add(binder.Name.ToLower(), value);
SourceItems.Add(binder.Name.ToLower(), value);
}
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (_dictionary != null)
if (SourceItems != null)
{
if (_dictionary.TryGetValue(binder.Name.ToLower(), out result))
if (SourceItems.TryGetValue(binder.Name.ToLower(), out result))
{
return true;
}

View File

@@ -81,7 +81,7 @@ namespace Umbraco.Core.Dynamics
}
//Go ahead and try to fetch all of the elements matching the member name, and wrap them
var elements = BaseElement.Elements(binder.Name);
if (elements.Count() == 0 && BaseElement.Name == "root" && BaseElement.Elements().Count() == 1)
if (!elements.Any() && BaseElement.Name == "root" && BaseElement.Elements().Count() == 1)
{
//no elements matched, lets try first child
elements = BaseElement.Elements().ElementAt(0).Elements(binder.Name);

View File

@@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Xml;
using System.Xml.Linq;
using Microsoft.CSharp.RuntimeBinder;
@@ -11,13 +12,41 @@ namespace Umbraco.Tests.DynamicDocument
public class DynamicXmlTests
{
[Test]
public void Ensure_Legacy_Objects_Are_Returned()
{
var xml = "<DAMP fullMedia=\"\"><mediaItem><Image id=\"1057\" version=\"d58d5c16-153e-4896-892f-a722e45a69af\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:55:29\" updateDate=\"2012-11-05T16:55:44\" nodeName=\"test12\" urlName=\"test12\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1057\"><umbracoFile>/media/54/tulips.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>620888</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:55:34\"><crop name=\"thumbCrop\" x=\"154\" y=\"1\" x2=\"922\" y2=\"768\" url=\"/media/54/tulips_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem><mediaItem><Image id=\"1055\" version=\"4df1f08a-3552-45f2-b4bf-fa980c762f4a\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:29:58\" updateDate=\"2012-11-05T16:30:27\" nodeName=\"Test\" urlName=\"test\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1055\"><umbracoFile>/media/41/hydrangeas.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>595284</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:30:18\"><crop name=\"thumbCrop\" x=\"133\" y=\"0\" x2=\"902\" y2=\"768\" url=\"/media/41/hydrangeas_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem></DAMP>";
var mediaItems = new global::umbraco.MacroEngines.DynamicXml(xml);
//Debug.WriteLine("full xml = {0}", mediaItems.ToXml());
if (mediaItems.Count() != 0)
{
foreach (dynamic item in mediaItems)
{
Type itemType = item.GetType();
Debug.WriteLine("item type = {0}", itemType);
dynamic image = item.Image;
Type imageType = image.GetType();
Debug.WriteLine("image type = {0}", imageType);
//ensure they are the same
Assert.AreEqual(itemType, imageType);
//ensure they are legacy
Assert.AreEqual(typeof(global::umbraco.MacroEngines.DynamicXml), itemType);
Assert.AreEqual(typeof(global::umbraco.MacroEngines.DynamicXml), imageType);
}
}
}
/// <summary>
/// Test the current Core class
/// </summary>
[Test]
public void Find_Test_Core_Class()
{
RunFindTest(x => new DynamicXml(x));
RunFindTest(x => new DynamicXml(x));
}
/// <summary>

View File

@@ -22,7 +22,11 @@ namespace umbraco.MacroEngines
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return _internal.TryGetMember(binder, out result);
var innerResult = _internal.TryGetMember(binder, out result);
//special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need
//to return the legacy type
result = LegacyConverter.ConvertToLegacy(result);
return innerResult;
}
}
}

View File

@@ -40,15 +40,27 @@ namespace umbraco.MacroEngines
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return _inner.TryGetMember(binder, out result);
var innerResult =_inner.TryGetMember(binder, out result);
//special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need
//to return the legacy type
result = LegacyConverter.ConvertToLegacy(result);
return innerResult;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
return _inner.TryGetIndex(binder, indexes, out result);
var innerResult = _inner.TryGetIndex(binder, indexes, out result);
//special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need
//to return the legacy type
result = LegacyConverter.ConvertToLegacy(result);
return innerResult;
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
return _inner.TryInvoke(binder, args, out result);
var innerResult = _inner.TryInvoke(binder, args, out result);
//special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need
//to return the legacy type
result = LegacyConverter.ConvertToLegacy(result);
return innerResult;
}
public bool IsNull()
{

View File

@@ -11,7 +11,6 @@ using System.Web;
namespace umbraco.MacroEngines
{
[Obsolete("This class has been superceded by Umbraco.Core.Dynamics.DynamicXml")]
public class DynamicXml : DynamicObject, IEnumerable
{
@@ -45,15 +44,27 @@ namespace umbraco.MacroEngines
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
return _inner.TryGetIndex(binder, indexes, out result);
var innerResult = _inner.TryGetIndex(binder, indexes, out result);
//special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need
//to return the legacy type
result = LegacyConverter.ConvertToLegacy(result);
return innerResult;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
return _inner.TryInvokeMember(binder, args, out result);
var innerResult = _inner.TryInvokeMember(binder, args, out result);
//special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need
//to return the legacy type
result = LegacyConverter.ConvertToLegacy(result);
return innerResult;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return _inner.TryGetMember(binder, out result);
var innerResult = _inner.TryGetMember(binder, out result);
//special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need
//to return the legacy type
result = LegacyConverter.ConvertToLegacy(result);
return innerResult;
}
public DynamicXml XPath(string expression)

View File

@@ -0,0 +1,29 @@
namespace umbraco.MacroEngines
{
internal static class LegacyConverter
{
/// <summary>
/// Checks if the object is DynamicXml or DynamicNull and ensures that we return the legacy class not the new one
/// as we want this class to always ensure we're dealing with the legacy classes
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
internal static object ConvertToLegacy(object result)
{
if (result is Umbraco.Core.Dynamics.DynamicXml)
{
result = new DynamicXml(((Umbraco.Core.Dynamics.DynamicXml)result).BaseElement);
}
else if (result is Umbraco.Core.Dynamics.DynamicNull)
{
result = new DynamicNull();
}
else if (result is Umbraco.Core.Dynamics.DynamicDictionary)
{
result = new DynamicDictionary(((Umbraco.Core.Dynamics.DynamicDictionary) result).SourceItems);
}
return result;
}
}
}

View File

@@ -86,6 +86,7 @@
<Compile Include="RazorDynamicNode\DynamicBackingItem.cs" />
<Compile Include="RazorDynamicNode\DynamicBackingItemType.cs" />
<Compile Include="RazorDynamicNode\DynamicClass.cs" />
<Compile Include="RazorDynamicNode\LegacyConverter.cs" />
<Compile Include="RazorDynamicNode\PublishedContentExtensions.cs" />
<Compile Include="RazorDynamicNode\DynamicExpression.cs" />
<Compile Include="RazorDynamicNode\DynamicGrouping.cs" />