From 1d0299af893499026a3bd37d4a2543c1f6156b7e Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 19 Feb 2013 13:58:16 -0100 Subject: [PATCH 01/18] U4-1611 - bugfix --- .../ContentStores/PublishContentStoreTests.cs | 3 +++ src/Umbraco.Web/DefaultPublishedContentStore.cs | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Tests/ContentStores/PublishContentStoreTests.cs b/src/Umbraco.Tests/ContentStores/PublishContentStoreTests.cs index 26594a57da..a8a335dd5a 100644 --- a/src/Umbraco.Tests/ContentStores/PublishContentStoreTests.cs +++ b/src/Umbraco.Tests/ContentStores/PublishContentStoreTests.cs @@ -54,6 +54,8 @@ namespace Umbraco.Tests.ContentStores + + "; @@ -155,6 +157,7 @@ namespace Umbraco.Tests.ContentStores [TestCase("/home/sub1", 1173)] [TestCase("/Home/sub1", 1173)] [TestCase("/home/Sub1", 1173)] //test different cases + [TestCase("/home/Sub'Apostrophe", 1177)] public void Get_Node_By_Route(string route, int nodeId) { var result = _publishedContentStore.GetDocumentByRoute(_umbracoContext, route, false); diff --git a/src/Umbraco.Web/DefaultPublishedContentStore.cs b/src/Umbraco.Web/DefaultPublishedContentStore.cs index e7e6519d96..227cc64e0c 100644 --- a/src/Umbraco.Web/DefaultPublishedContentStore.cs +++ b/src/Umbraco.Web/DefaultPublishedContentStore.cs @@ -29,7 +29,8 @@ namespace Umbraco.Web public string DescendantDocumentById { get; private set; } public string DescendantDocumentByAlias { get; private set; } public string ChildDocumentByUrlName { get; private set; } - public string RootDocumentWithLowestSortOrder { get; private set; } + public string ChildDocumentByUrlNameVar { get; private set; } + public string RootDocumentWithLowestSortOrder { get; private set; } public XPathStringsDefinition(int version) { @@ -46,6 +47,7 @@ namespace Umbraco.Web + " or contains(concat(',',translate(data [@alias='umbracoUrlAlias'], ' ', ''),','),',/{0},')" + ")]"; ChildDocumentByUrlName = "/node [@urlName='{0}']"; + ChildDocumentByUrlNameVar = "/node [@urlName=${0}]"; RootDocumentWithLowestSortOrder = "/root/node [not(@sortOrder > ../node/@sortOrder)][1]"; break; @@ -58,6 +60,7 @@ namespace Umbraco.Web + " or contains(concat(',',translate(umbracoUrlAlias, ' ', ''),','),',/{0},')" + ")]"; ChildDocumentByUrlName = "/* [@isDoc and @urlName='{0}']"; + ChildDocumentByUrlNameVar = "/* [@isDoc and @urlName=${0}]"; RootDocumentWithLowestSortOrder = "/root/* [@isDoc and not(@sortOrder > ../* [@isDoc]/@sortOrder)][1]"; break; @@ -245,12 +248,18 @@ namespace Umbraco.Web varsList = varsList ?? new List(); var varName = string.Format("var{0}", partsIndex); varsList.Add(new XPathVariable(varName, part)); - part = "$" + varName; + xpathBuilder.AppendFormat(XPathStrings.ChildDocumentByUrlNameVar, varName); + } + else + { + xpathBuilder.AppendFormat(XPathStrings.ChildDocumentByUrlName, part); + } - xpathBuilder.AppendFormat(XPathStrings.ChildDocumentByUrlName, part); } xpath = xpathBuilder.ToString(); + if (varsList != null) + vars = varsList.ToArray(); } return xpath; From 8bb447065cf36d150e267d740dd7f4bfdb8d5284 Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 19 Feb 2013 17:45:22 -0100 Subject: [PATCH 02/18] Tests - cleanup settings handling for more reliable tests --- .../Configuration/UmbracoSettings.cs | 24 ++-- .../Routing/LookupByAliasTests.cs | 6 - .../LookupByNiceUrlAndTemplateTests.cs | 6 - .../Routing/LookupByNiceUrlTests.cs | 11 +- .../LookupByNiceUrlWithDomainsTests.cs | 12 +- .../Routing/NiceUrlProviderTests.cs | 65 +++++----- .../NiceUrlsProviderWithDomainsTests.cs | 61 ++++------ .../Routing/RenderRouteHandlerTests.cs | 3 +- .../Routing/UmbracoModuleTests.cs | 11 +- .../Routing/UrlsWithNestedDomains.cs | 15 +-- .../Routing/uQueryGetNodeIdByUrlTests.cs | 21 +--- .../TestHelpers/BaseRoutingTest.cs | 12 -- src/Umbraco.Tests/TestHelpers/BaseWebTest.cs | 6 +- .../TestHelpers/SettingsForTests.cs | 114 ++++++++++++++++++ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + 15 files changed, 200 insertions(+), 168 deletions(-) create mode 100644 src/Umbraco.Tests/TestHelpers/SettingsForTests.cs diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs index 055353f4b5..ec1249e8ea 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs @@ -25,11 +25,8 @@ namespace Umbraco.Core.Configuration /// internal class UmbracoSettings { - private static bool GetKeyWithOverride(string key, bool defaultValue, bool? overrideValue) + private static bool GetKeyValue(string key, bool defaultValue) { - if (overrideValue.HasValue) - return overrideValue.Value; - bool value; string stringValue = GetKey(key); @@ -40,11 +37,8 @@ namespace Umbraco.Core.Configuration return defaultValue; } - private static int GetKeyWithOverride(string key, int defaultValue, int? overrideValue) + private static int GetKeyValue(string key, int defaultValue) { - if (overrideValue.HasValue) - return overrideValue.Value; - int value; string stringValue = GetKey(key); @@ -405,7 +399,7 @@ namespace Umbraco.Core.Configuration get { // default: false - return GetKeyWithOverride("/settings/requestHandler/useDomainPrefixes", false, _useDomainPrefixes); + return _useDomainPrefixes ?? GetKeyValue("/settings/requestHandler/useDomainPrefixes", false); } internal set { @@ -426,7 +420,7 @@ namespace Umbraco.Core.Configuration { // default: false return GlobalSettings.UseDirectoryUrls - && GetKeyWithOverride("/settings/requestHandler/addTrailingSlash", false, _addTrailingSlash); + && (_addTrailingSlash ?? GetKeyValue("/settings/requestHandler/addTrailingSlash", false)); } internal set { @@ -649,7 +643,7 @@ namespace Umbraco.Core.Configuration get { // default: true - return GetKeyWithOverride("/settings/content/ForceSafeAliases", true, _forceSafeAliases); + return _forceSafeAliases ?? GetKeyValue("/settings/content/ForceSafeAliases", true); } internal set { @@ -668,7 +662,7 @@ namespace Umbraco.Core.Configuration get { // default: false - return GetKeyWithOverride("/settings/web.routing/@trySkipIisCustomErrors", false, _trySkipIisCustomErrors); + return _trySkipIisCustomErrors ?? GetKeyValue("/settings/web.routing/@trySkipIisCustomErrors", false); } internal set { @@ -706,7 +700,7 @@ namespace Umbraco.Core.Configuration get { // default: 1800 - return GetKeyWithOverride("/settings/content/UmbracoLibraryCacheDuration", 1800, _umbracoLibraryCacheDuration); + return _umbracoLibraryCacheDuration ?? GetKeyValue("/settings/content/UmbracoLibraryCacheDuration", 1800); } internal set { @@ -1069,11 +1063,11 @@ namespace Umbraco.Core.Configuration get { // default: true - return GetKeyWithOverride("/settings/content/UseLegacyXmlSchema", true, _useLegacySchema); + return _useLegacySchema ?? GetKeyValue("/settings/content/UseLegacyXmlSchema", true); } internal set { - // used for unit testing + // used for unit testing _useLegacySchema = value; } } diff --git a/src/Umbraco.Tests/Routing/LookupByAliasTests.cs b/src/Umbraco.Tests/Routing/LookupByAliasTests.cs index f8a72c5c7c..af1ee7528c 100644 --- a/src/Umbraco.Tests/Routing/LookupByAliasTests.cs +++ b/src/Umbraco.Tests/Routing/LookupByAliasTests.cs @@ -7,12 +7,6 @@ namespace Umbraco.Tests.Routing [TestFixture] public class LookupByAliasTests : BaseRoutingTest { - public override void Initialize() - { - base.Initialize(); - Core.Configuration.UmbracoSettings.UseLegacyXmlSchema = false; - } - /// /// We don't need a db for this test, will run faster without one /// diff --git a/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs b/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs index 72ad748283..0068b7180c 100644 --- a/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs +++ b/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs @@ -9,12 +9,6 @@ namespace Umbraco.Tests.Routing [TestFixture] public class LookupByNiceUrlAndTemplateTests : BaseRoutingTest { - public override void Initialize() - { - base.Initialize(); - Umbraco.Core.Configuration.UmbracoSettings.UseLegacyXmlSchema = false; - } - [TestCase("/blah")] [TestCase("/default.aspx/blah")] //this one is actually rather important since this is the path that comes through when we are running in pre-IIS 7 for the root document '/' ! [TestCase("/home/Sub1/blah")] diff --git a/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs b/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs index 2bce2907ce..2e31198a39 100644 --- a/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs +++ b/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs @@ -10,12 +10,6 @@ namespace Umbraco.Tests.Routing [TestFixture] public class LookupByNiceUrlTests : BaseRoutingTest { - public override void Initialize() - { - base.Initialize(); - Umbraco.Core.Configuration.UmbracoSettings.UseLegacyXmlSchema = false; - } - /// /// We don't need a db for this test, will run faster without one /// @@ -41,7 +35,7 @@ namespace Umbraco.Tests.Routing var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url var docreq = new PublishedContentRequest(url, routingContext); var lookup = new LookupByNiceUrl(); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true"); + SettingsForTests.HideTopLevelNodeFromPath = true; var result = lookup.TrySetDocument(docreq); @@ -68,7 +62,8 @@ namespace Umbraco.Tests.Routing var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url var docreq = new PublishedContentRequest(url, routingContext); var lookup = new LookupByNiceUrl(); - + SettingsForTests.HideTopLevelNodeFromPath = false; + var result = lookup.TrySetDocument(docreq); Assert.IsTrue(result); diff --git a/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs b/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs index 9a0e708b32..0fe5b1f679 100644 --- a/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs @@ -18,16 +18,8 @@ namespace Umbraco.Tests.Routing { base.Initialize(); InitializeLanguagesAndDomains(); - Umbraco.Core.Configuration.UmbracoSettings.UseLegacyXmlSchema = false; } - public override void TearDown() - { - base.TearDown(); - - } - - void InitializeLanguagesAndDomains() { var domains = Domain.GetDomains(); @@ -154,7 +146,7 @@ namespace Umbraco.Tests.Routing { SetDomains3(); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true"); + SettingsForTests.HideTopLevelNodeFromPath = true; var routingContext = GetRoutingContext(url); var uri = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url @@ -193,7 +185,7 @@ namespace Umbraco.Tests.Routing { SetDomains4(); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true"); + SettingsForTests.HideTopLevelNodeFromPath = true; var routingContext = GetRoutingContext(url); var uri = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url diff --git a/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs b/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs index 00ae2f522c..3b51e32040 100644 --- a/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs +++ b/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs @@ -25,18 +25,7 @@ namespace Umbraco.Tests.Routing Path.Combine(currDir.Parent.Parent.FullName, "config", "umbracoSettings.config"), true); - Core.Configuration.UmbracoSettings.SettingsFilePath = Core.IO.IOHelper.MapPath(Core.IO.SystemDirectories.Config + Path.DirectorySeparatorChar, false); - - - Umbraco.Core.Configuration.UmbracoSettings.UseLegacyXmlSchema = false; - } - - public override void TearDown() - { - base.TearDown(); - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", ""); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", ""); + SettingsForTests.SettingsFilePath = Core.IO.IOHelper.MapPath(Core.IO.SystemDirectories.Config + Path.DirectorySeparatorChar, false); } internal override IRoutesCache GetRoutesCache() @@ -53,17 +42,19 @@ namespace Umbraco.Tests.Routing public void Ensure_Cache_Is_Correct() { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; + SettingsForTests.AddTrailingSlash = false; // (cached routes have none) var samples = new Dictionary { { 1046, "/home" }, - { 1173, "/home/sub1/" }, - { 1174, "/home/sub1/sub2/" }, - { 1176, "/home/sub1/sub-3/" }, - { 1177, "/home/sub1/custom-sub-1/" }, - { 1178, "/home/sub1/custom-sub-2/" }, - { 1175, "/home/sub-2/" }, - { 1172, "/test-page/" } + { 1173, "/home/sub1" }, + { 1174, "/home/sub1/sub2" }, + { 1176, "/home/sub1/sub-3" }, + { 1177, "/home/sub1/custom-sub-1" }, + { 1178, "/home/sub1/custom-sub-2" }, + { 1175, "/home/sub-2" }, + { 1172, "/test-page" } }; foreach (var sample in samples) @@ -72,7 +63,7 @@ namespace Umbraco.Tests.Routing Assert.AreEqual(sample.Value, result); } - var randomSample = new KeyValuePair(1177, "/home/sub1/custom-sub-1/"); + var randomSample = new KeyValuePair(1177, "/home/sub1/custom-sub-1"); for (int i = 0; i < 5; i++) { var result = routingContext.NiceUrlProvider.GetNiceUrl(randomSample.Key); @@ -112,9 +103,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; + SettingsForTests.UseDomainPrefixes = false; var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId); Assert.AreEqual(niceUrlMatch, result); @@ -135,9 +126,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true"); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = true; + SettingsForTests.UseDomainPrefixes = false; var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId); Assert.AreEqual(niceUrlMatch, result); @@ -148,16 +139,16 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("http://example.com/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDomainPrefixes = false; Assert.AreEqual("/home/sub1/custom-sub-1/", routingContext.NiceUrlProvider.GetNiceUrl(1177)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true; + SettingsForTests.UseDomainPrefixes = true; Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", routingContext.NiceUrlProvider.GetNiceUrl(1177)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDomainPrefixes = false; routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true; Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", routingContext.NiceUrlProvider.GetNiceUrl(1177)); } @@ -167,14 +158,14 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("http://example.com/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDomainPrefixes = false; Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true; + SettingsForTests.UseDomainPrefixes = true; Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDomainPrefixes = false; routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true; Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999)); } diff --git a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs index f05818541b..03e9d31ee7 100644 --- a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs @@ -14,20 +14,11 @@ namespace Umbraco.Tests.Routing [TestFixture] public class NiceUrlsProviderWithDomainsTests : BaseRoutingTest { - public override void TearDown() - { - base.TearDown(); - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", ""); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", ""); - } - internal override IRoutesCache GetRoutesCache() { return new DefaultRoutesCache(false); } - void InitializeLanguagesAndDomains() { var domains = Domain.GetDomains(); @@ -195,9 +186,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; InitializeLanguagesAndDomains(); SetDomains1(); @@ -224,9 +215,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; InitializeLanguagesAndDomains(); SetDomains2(); @@ -245,9 +236,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; InitializeLanguagesAndDomains(); SetDomains3(); @@ -271,11 +262,11 @@ namespace Umbraco.Tests.Routing public void Get_Nice_Url_NestedDomains(int nodeId, string currentUrl, bool absolute, string expected) { var routingContext = GetRoutingContext("/test", 1111); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; + InitializeLanguagesAndDomains(); SetDomains4(); @@ -289,9 +280,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; InitializeLanguagesAndDomains(); SetDomains4(); @@ -348,22 +339,22 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("http://domain1.com/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; InitializeLanguagesAndDomains(); SetDomains4(); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; - Assert.AreEqual("/en/1001-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100111)); + SettingsForTests.UseDomainPrefixes = false; + Assert.AreEqual("/en/1001-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100111)); Assert.AreEqual("http://domain3.com/en/1003-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100311)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true; - Assert.AreEqual("http://domain1.com/en/1001-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100111)); + SettingsForTests.UseDomainPrefixes = true; + Assert.AreEqual("http://domain1.com/en/1001-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100111)); Assert.AreEqual("http://domain3.com/en/1003-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100311)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; - routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true; + SettingsForTests.UseDomainPrefixes = false; + routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true; Assert.AreEqual("http://domain1.com/en/1001-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100111)); Assert.AreEqual("http://domain3.com/en/1003-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100311)); } @@ -373,8 +364,8 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("http://domain1.com/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; InitializeLanguagesAndDomains(); SetDomains5(); diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index 9657ed0493..50edab90ce 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -27,7 +27,7 @@ namespace Umbraco.Tests.Routing base.Initialize(); - System.Configuration.ConfigurationManager.AppSettings.Set("umbracoPath", "~/umbraco"); + SettingsForTests.UmbracoPath = "~/umbraco"; var webBoot = new WebBootManager(new UmbracoApplication(), true); //webBoot.Initialize(); @@ -40,7 +40,6 @@ namespace Umbraco.Tests.Routing { base.TearDown(); RouteTable.Routes.Clear(); - System.Configuration.ConfigurationManager.AppSettings.Set("umbracoPath", ""); SurfaceControllerResolver.Reset(); } diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs index aa6ec83ec6..34aec56aed 100644 --- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs +++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs @@ -58,9 +58,9 @@ namespace Umbraco.Tests.Routing //create the module _module = new UmbracoModule(); - ConfigurationManager.AppSettings.Set("umbracoConfigurationStatus", UmbracoVersion.Current.ToString(3)); - ConfigurationManager.AppSettings.Set("umbracoReservedPaths", "~/umbraco,~/install/"); - ConfigurationManager.AppSettings.Set("umbracoReservedUrls", "~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd"); + SettingsForTests.ConfigurationStatus = UmbracoVersion.Current.ToString(3); + SettingsForTests.ReservedPaths = "~/umbraco,~/install/"; + SettingsForTests.ReservedUrls = "~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd"; //create the not found handlers config using (var sw = File.CreateText(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemFiles.NotFoundhandlersConfig, false))) @@ -79,11 +79,6 @@ namespace Umbraco.Tests.Routing base.TearDown(); _module.DisposeIfDisposable(); - - //reset the app config - ConfigurationManager.AppSettings.Set("umbracoConfigurationStatus", ""); - ConfigurationManager.AppSettings.Set("umbracoReservedPaths", ""); - ConfigurationManager.AppSettings.Set("umbracoReservedUrls", ""); } // do not test for /base here as it's handled before EnsureUmbracoRoutablePage is called diff --git a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs index 17f5f190d2..858ef9c85b 100644 --- a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs +++ b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs @@ -22,9 +22,9 @@ namespace Umbraco.Tests.Routing [Test] public void DoNotPolluteCache() { - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; InitializeLanguagesAndDomains(); SetDomains1(); @@ -64,15 +64,6 @@ namespace Umbraco.Tests.Routing //Assert.AreEqual("http://domain1.com/1001-1/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111, true)); // bad } - public override void TearDown() - { - base.TearDown(); - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", ""); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", ""); - - } - internal override IRoutesCache GetRoutesCache() { return new DefaultRoutesCache(false); diff --git a/src/Umbraco.Tests/Routing/uQueryGetNodeIdByUrlTests.cs b/src/Umbraco.Tests/Routing/uQueryGetNodeIdByUrlTests.cs index 008c73e4c7..ab0aa6cb37 100644 --- a/src/Umbraco.Tests/Routing/uQueryGetNodeIdByUrlTests.cs +++ b/src/Umbraco.Tests/Routing/uQueryGetNodeIdByUrlTests.cs @@ -16,14 +16,6 @@ namespace Umbraco.Tests.Routing [TestFixture] public class uQueryGetNodeIdByUrlTests : BaseRoutingTest { - public override void TearDown() - { - base.TearDown(); - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", ""); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", ""); - } - internal override IRoutesCache GetRoutesCache() { return new DefaultRoutesCache(false); @@ -70,10 +62,9 @@ namespace Umbraco.Tests.Routing public void GetNodeIdByUrl_Not_Hiding_Top_Level_Absolute(int nodeId, string url) { - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; + SettingsForTests.UseDomainPrefixes = false; Assert.AreEqual(nodeId, global::umbraco.uQuery.GetNodeIdByUrl("http://example.com" + url)); } @@ -89,9 +80,9 @@ namespace Umbraco.Tests.Routing public void GetNodeIdByUrl_Not_Hiding_Top_Level_Relative(int nodeId, string url) { - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; + SettingsForTests.UseDomainPrefixes = false; Assert.AreEqual(nodeId, global::umbraco.uQuery.GetNodeIdByUrl(url)); } diff --git a/src/Umbraco.Tests/TestHelpers/BaseRoutingTest.cs b/src/Umbraco.Tests/TestHelpers/BaseRoutingTest.cs index 585733e309..a8cede160d 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseRoutingTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseRoutingTest.cs @@ -13,18 +13,6 @@ namespace Umbraco.Tests.TestHelpers [TestFixture, RequiresSTA] public abstract class BaseRoutingTest : BaseWebTest { - public override void Initialize() - { - base.Initialize(); - } - - public override void TearDown() - { - base.TearDown(); - - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", ""); - } - /// /// Return a new RoutingContext /// diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs index 4f1e3c158e..7152b158e1 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs @@ -24,7 +24,9 @@ namespace Umbraco.Tests.TestHelpers [SetUp] public virtual void Initialize() { - TestHelper.SetupLog4NetForTests(); + SettingsForTests.Reset(); + + TestHelper.SetupLog4NetForTests(); TestHelper.InitializeContentDirectories(); AppDomain.CurrentDomain.SetData("DataDirectory", TestHelper.CurrentAssemblyDirectory); @@ -66,7 +68,7 @@ namespace Umbraco.Tests.TestHelpers Cache.ClearAllCache(); - UmbracoSettings.ResetSetters(); + SettingsForTests.Reset(); } protected virtual void CreateDirectories(string[] directories) diff --git a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs new file mode 100644 index 0000000000..69525d361d --- /dev/null +++ b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Configuration; +using Umbraco.Core.Configuration; + +namespace Umbraco.Tests.TestHelpers +{ + class SettingsForTests + { + // umbracoSettings + + public static bool UseLegacyXmlSchema + { + get { return UmbracoSettings.UseLegacyXmlSchema; } + set { UmbracoSettings.UseLegacyXmlSchema = value; } + } + + public static bool AddTrailingSlash + { + get { return UmbracoSettings.AddTrailingSlash; } + set { UmbracoSettings.AddTrailingSlash = value; } + } + + public static bool UseDomainPrefixes + { + get { return UmbracoSettings.UseDomainPrefixes; } + set { UmbracoSettings.UseDomainPrefixes = value; } + } + + public static string SettingsFilePath + { + get { return UmbracoSettings.SettingsFilePath; } + set { UmbracoSettings.SettingsFilePath = value; } + } + + // from appSettings + + private static readonly IDictionary SavedAppSettings = new Dictionary(); + + static void SaveSetting(string key) + { + SavedAppSettings[key] = ConfigurationManager.AppSettings[key]; + } + + static void SaveSettings() + { + SaveSetting("umbracoHideTopLevelNodeFromPath"); + SaveSetting("umbracoUseDirectoryUrls"); + SaveSetting("umbracoPath"); + SaveSetting("umbracoReservedPaths"); + SaveSetting("umbracoReservedUrls"); + SaveSetting("umbracoConfigurationStatus"); + + SaveSetting(GlobalSettings.UmbracoConnectionName); + } + + public static bool HideTopLevelNodeFromPath + { + get { return GlobalSettings.HideTopLevelNodeFromPath; } + set { ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", value ? "true" : "false"); } + } + + public static bool UseDirectoryUrls + { + get { return GlobalSettings.UseDirectoryUrls; } + set { ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", value ? "true" : "false"); } + } + + public static string UmbracoPath + { + get { return GlobalSettings.Path; } + set { ConfigurationManager.AppSettings.Set("umbracoPath", value); } + } + + public static string ReservedPaths + { + get { return GlobalSettings.ReservedPaths; } + set { ConfigurationManager.AppSettings.Set("umbracoReservedPaths", value); } + } + + public static string ReservedUrls + { + get { return GlobalSettings.ReservedUrls; } + set { ConfigurationManager.AppSettings.Set("umbracoReservedUrls", value); } + } + + public static string ConfigurationStatus + { + get { return GlobalSettings.ConfigurationStatus; } + set { ConfigurationManager.AppSettings.Set("umbracoConfigurationStatus", value); } + } + + // reset & defaults + + static SettingsForTests() + { + SaveSettings(); + } + + public static void Reset() + { + UmbracoSettings.ResetSetters(); + + foreach (var kvp in SavedAppSettings) + ConfigurationManager.AppSettings.Set(kvp.Key, kvp.Value); + + // set some defaults that are wrong in the config file?! + // this is annoying, really + HideTopLevelNodeFromPath = false; + } + } +} diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 0824305bd9..2b631b8cbf 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -285,6 +285,7 @@ + From 9c8b5cd97e0df2cc82917035d6b2d7282a7a17fb Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 19 Feb 2013 17:49:49 -0100 Subject: [PATCH 03/18] U4-1441 - fix, fix and fix! --- src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs index 452205ba8b..72fec51add 100644 --- a/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs +++ b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs @@ -68,8 +68,13 @@ namespace Umbraco.Web.Routing LogHelper.Debug("Lookup '{0}' found node with id={1}.", () => lookup.GetType().FullName, () => docRequest.PublishedContent.Id); if (docRequest.Is404) LogHelper.Debug("Lookup '{0}' set status to 404.", () => lookup.GetType().FullName); + + // if we found a document, break, don't look at more handler -- we're done + break; } - break; + + // if we did not find a document, continue, look at other handlers + continue; } // else it's a legacy handler, run @@ -108,8 +113,11 @@ namespace Umbraco.Web.Routing // string.Format("Added to cache '{0}', {1}.", url, handler.redirectID)); //} + // if we found a document, break, don't look at more handler -- we're done break; } + + // if we did not find a document, continue, look at other handlers } } From 04c9771978a5d4c0d813e43a92852a2bfb51c3bb Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 19 Feb 2013 13:58:16 -0100 Subject: [PATCH 04/18] U4-1611 - bugfix --- .../ContentStores/PublishContentStoreTests.cs | 3 +++ src/Umbraco.Web/DefaultPublishedContentStore.cs | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Tests/ContentStores/PublishContentStoreTests.cs b/src/Umbraco.Tests/ContentStores/PublishContentStoreTests.cs index 26594a57da..a8a335dd5a 100644 --- a/src/Umbraco.Tests/ContentStores/PublishContentStoreTests.cs +++ b/src/Umbraco.Tests/ContentStores/PublishContentStoreTests.cs @@ -54,6 +54,8 @@ namespace Umbraco.Tests.ContentStores + + "; @@ -155,6 +157,7 @@ namespace Umbraco.Tests.ContentStores [TestCase("/home/sub1", 1173)] [TestCase("/Home/sub1", 1173)] [TestCase("/home/Sub1", 1173)] //test different cases + [TestCase("/home/Sub'Apostrophe", 1177)] public void Get_Node_By_Route(string route, int nodeId) { var result = _publishedContentStore.GetDocumentByRoute(_umbracoContext, route, false); diff --git a/src/Umbraco.Web/DefaultPublishedContentStore.cs b/src/Umbraco.Web/DefaultPublishedContentStore.cs index 215461243c..5a86d3c6c6 100644 --- a/src/Umbraco.Web/DefaultPublishedContentStore.cs +++ b/src/Umbraco.Web/DefaultPublishedContentStore.cs @@ -29,7 +29,8 @@ namespace Umbraco.Web public string DescendantDocumentById { get; private set; } public string DescendantDocumentByAlias { get; private set; } public string ChildDocumentByUrlName { get; private set; } - public string RootDocumentWithLowestSortOrder { get; private set; } + public string ChildDocumentByUrlNameVar { get; private set; } + public string RootDocumentWithLowestSortOrder { get; private set; } public XPathStringsDefinition(int version) { @@ -46,6 +47,7 @@ namespace Umbraco.Web + " or contains(concat(',',translate(data [@alias='umbracoUrlAlias'], ' ', ''),','),',/{0},')" + ")]"; ChildDocumentByUrlName = "/node [@urlName='{0}']"; + ChildDocumentByUrlNameVar = "/node [@urlName=${0}]"; RootDocumentWithLowestSortOrder = "/root/node [not(@sortOrder > ../node/@sortOrder)][1]"; break; @@ -58,6 +60,7 @@ namespace Umbraco.Web + " or contains(concat(',',translate(umbracoUrlAlias, ' ', ''),','),',/{0},')" + ")]"; ChildDocumentByUrlName = "/* [@isDoc and @urlName='{0}']"; + ChildDocumentByUrlNameVar = "/* [@isDoc and @urlName=${0}]"; RootDocumentWithLowestSortOrder = "/root/* [@isDoc and not(@sortOrder > ../* [@isDoc]/@sortOrder)][1]"; break; @@ -248,12 +251,18 @@ namespace Umbraco.Web varsList = varsList ?? new List(); var varName = string.Format("var{0}", partsIndex); varsList.Add(new XPathVariable(varName, part)); - part = "$" + varName; + xpathBuilder.AppendFormat(XPathStrings.ChildDocumentByUrlNameVar, varName); + } + else + { + xpathBuilder.AppendFormat(XPathStrings.ChildDocumentByUrlName, part); + } - xpathBuilder.AppendFormat(XPathStrings.ChildDocumentByUrlName, part); } xpath = xpathBuilder.ToString(); + if (varsList != null) + vars = varsList.ToArray(); } return xpath; From 60bbede40845a8646c9fec9f207d30540c9cb328 Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 19 Feb 2013 17:49:49 -0100 Subject: [PATCH 05/18] U4-1441 - fix, fix and fix! --- src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs index 452205ba8b..72fec51add 100644 --- a/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs +++ b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs @@ -68,8 +68,13 @@ namespace Umbraco.Web.Routing LogHelper.Debug("Lookup '{0}' found node with id={1}.", () => lookup.GetType().FullName, () => docRequest.PublishedContent.Id); if (docRequest.Is404) LogHelper.Debug("Lookup '{0}' set status to 404.", () => lookup.GetType().FullName); + + // if we found a document, break, don't look at more handler -- we're done + break; } - break; + + // if we did not find a document, continue, look at other handlers + continue; } // else it's a legacy handler, run @@ -108,8 +113,11 @@ namespace Umbraco.Web.Routing // string.Format("Added to cache '{0}', {1}.", url, handler.redirectID)); //} + // if we found a document, break, don't look at more handler -- we're done break; } + + // if we did not find a document, continue, look at other handlers } } From c3ccf3a609855870df0f079f33d3655d9c453e51 Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 19 Feb 2013 18:01:52 -0100 Subject: [PATCH 06/18] Tests - cleanup settings handling for more reliable tests --- .../Configuration/UmbracoSettings.cs | 24 ++-- .../Routing/LookupByAliasTests.cs | 6 - .../LookupByNiceUrlAndTemplateTests.cs | 6 - .../Routing/LookupByNiceUrlTests.cs | 11 +- .../LookupByNiceUrlWithDomainsTests.cs | 12 +- .../Routing/NiceUrlProviderTests.cs | 65 +++++----- .../NiceUrlsProviderWithDomainsTests.cs | 61 ++++------ .../Routing/RenderRouteHandlerTests.cs | 3 +- .../Routing/UmbracoModuleTests.cs | 11 +- .../Routing/UrlsWithNestedDomains.cs | 15 +-- .../Routing/uQueryGetNodeIdByUrlTests.cs | 21 +--- .../TestHelpers/BaseRoutingTest.cs | 12 -- src/Umbraco.Tests/TestHelpers/BaseWebTest.cs | 6 +- .../TestHelpers/SettingsForTests.cs | 114 ++++++++++++++++++ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + 15 files changed, 200 insertions(+), 168 deletions(-) create mode 100644 src/Umbraco.Tests/TestHelpers/SettingsForTests.cs diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs index 554f8c7e19..9abf225166 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs @@ -25,11 +25,8 @@ namespace Umbraco.Core.Configuration /// internal class UmbracoSettings { - private static bool GetKeyWithOverride(string key, bool defaultValue, bool? overrideValue) + private static bool GetKeyValue(string key, bool defaultValue) { - if (overrideValue.HasValue) - return overrideValue.Value; - bool value; string stringValue = GetKey(key); @@ -40,11 +37,8 @@ namespace Umbraco.Core.Configuration return defaultValue; } - private static int GetKeyWithOverride(string key, int defaultValue, int? overrideValue) + private static int GetKeyValue(string key, int defaultValue) { - if (overrideValue.HasValue) - return overrideValue.Value; - int value; string stringValue = GetKey(key); @@ -404,7 +398,7 @@ namespace Umbraco.Core.Configuration get { // default: false - return GetKeyWithOverride("/settings/requestHandler/useDomainPrefixes", false, _useDomainPrefixes); + return _useDomainPrefixes ?? GetKeyValue("/settings/requestHandler/useDomainPrefixes", false); } internal set { @@ -425,7 +419,7 @@ namespace Umbraco.Core.Configuration { // default: false return GlobalSettings.UseDirectoryUrls - && GetKeyWithOverride("/settings/requestHandler/addTrailingSlash", false, _addTrailingSlash); + && (_addTrailingSlash ?? GetKeyValue("/settings/requestHandler/addTrailingSlash", false)); } internal set { @@ -648,7 +642,7 @@ namespace Umbraco.Core.Configuration get { // default: true - return GetKeyWithOverride("/settings/content/ForceSafeAliases", true, _forceSafeAliases); + return _forceSafeAliases ?? GetKeyValue("/settings/content/ForceSafeAliases", true); } internal set { @@ -667,7 +661,7 @@ namespace Umbraco.Core.Configuration get { // default: false - return GetKeyWithOverride("/settings/web.routing/@trySkipIisCustomErrors", false, _trySkipIisCustomErrors); + return _trySkipIisCustomErrors ?? GetKeyValue("/settings/web.routing/@trySkipIisCustomErrors", false); } internal set { @@ -705,7 +699,7 @@ namespace Umbraco.Core.Configuration get { // default: 1800 - return GetKeyWithOverride("/settings/content/UmbracoLibraryCacheDuration", 1800, _umbracoLibraryCacheDuration); + return _umbracoLibraryCacheDuration ?? GetKeyValue("/settings/content/UmbracoLibraryCacheDuration", 1800); } internal set { @@ -1068,11 +1062,11 @@ namespace Umbraco.Core.Configuration get { // default: true - return GetKeyWithOverride("/settings/content/UseLegacyXmlSchema", true, _useLegacySchema); + return _useLegacySchema ?? GetKeyValue("/settings/content/UseLegacyXmlSchema", true); } internal set { - // used for unit testing + // used for unit testing _useLegacySchema = value; } } diff --git a/src/Umbraco.Tests/Routing/LookupByAliasTests.cs b/src/Umbraco.Tests/Routing/LookupByAliasTests.cs index 975ab16cbf..53f5dee14d 100644 --- a/src/Umbraco.Tests/Routing/LookupByAliasTests.cs +++ b/src/Umbraco.Tests/Routing/LookupByAliasTests.cs @@ -9,12 +9,6 @@ namespace Umbraco.Tests.Routing [TestFixture] public class LookupByAliasTests : BaseRoutingTest { - public override void Initialize() - { - base.Initialize(); - Umbraco.Core.Configuration.UmbracoSettings.UseLegacyXmlSchema = false; - } - /// /// We don't need a db for this test, will run faster without one /// diff --git a/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs b/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs index 72ad748283..0068b7180c 100644 --- a/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs +++ b/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs @@ -9,12 +9,6 @@ namespace Umbraco.Tests.Routing [TestFixture] public class LookupByNiceUrlAndTemplateTests : BaseRoutingTest { - public override void Initialize() - { - base.Initialize(); - Umbraco.Core.Configuration.UmbracoSettings.UseLegacyXmlSchema = false; - } - [TestCase("/blah")] [TestCase("/default.aspx/blah")] //this one is actually rather important since this is the path that comes through when we are running in pre-IIS 7 for the root document '/' ! [TestCase("/home/Sub1/blah")] diff --git a/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs b/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs index 3213209c22..0cf954c09e 100644 --- a/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs +++ b/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs @@ -10,12 +10,6 @@ namespace Umbraco.Tests.Routing [TestFixture] public class LookupByNiceUrlTests : BaseRoutingTest { - public override void Initialize() - { - base.Initialize(); - Umbraco.Core.Configuration.UmbracoSettings.UseLegacyXmlSchema = false; - } - /// /// We don't need a db for this test, will run faster without one /// @@ -42,7 +36,7 @@ namespace Umbraco.Tests.Routing var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url var docreq = new PublishedContentRequest(url, routingContext); var lookup = new LookupByNiceUrl(); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true"); + SettingsForTests.HideTopLevelNodeFromPath = true; var result = lookup.TrySetDocument(docreq); @@ -70,7 +64,8 @@ namespace Umbraco.Tests.Routing var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url var docreq = new PublishedContentRequest(url, routingContext); var lookup = new LookupByNiceUrl(); - + SettingsForTests.HideTopLevelNodeFromPath = false; + var result = lookup.TrySetDocument(docreq); Assert.IsTrue(result); diff --git a/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs b/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs index 9a0e708b32..0fe5b1f679 100644 --- a/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs @@ -18,16 +18,8 @@ namespace Umbraco.Tests.Routing { base.Initialize(); InitializeLanguagesAndDomains(); - Umbraco.Core.Configuration.UmbracoSettings.UseLegacyXmlSchema = false; } - public override void TearDown() - { - base.TearDown(); - - } - - void InitializeLanguagesAndDomains() { var domains = Domain.GetDomains(); @@ -154,7 +146,7 @@ namespace Umbraco.Tests.Routing { SetDomains3(); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true"); + SettingsForTests.HideTopLevelNodeFromPath = true; var routingContext = GetRoutingContext(url); var uri = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url @@ -193,7 +185,7 @@ namespace Umbraco.Tests.Routing { SetDomains4(); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true"); + SettingsForTests.HideTopLevelNodeFromPath = true; var routingContext = GetRoutingContext(url); var uri = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url diff --git a/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs b/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs index 4f72d0765c..ee86f6f127 100644 --- a/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs +++ b/src/Umbraco.Tests/Routing/NiceUrlProviderTests.cs @@ -25,18 +25,7 @@ namespace Umbraco.Tests.Routing Path.Combine(currDir.Parent.Parent.FullName, "config", "umbracoSettings.config"), true); - Core.Configuration.UmbracoSettings.SettingsFilePath = Core.IO.IOHelper.MapPath(Core.IO.SystemDirectories.Config + Path.DirectorySeparatorChar, false); - - - Umbraco.Core.Configuration.UmbracoSettings.UseLegacyXmlSchema = false; - } - - public override void TearDown() - { - base.TearDown(); - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", ""); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", ""); + SettingsForTests.SettingsFilePath = Core.IO.IOHelper.MapPath(Core.IO.SystemDirectories.Config + Path.DirectorySeparatorChar, false); } internal override IRoutesCache GetRoutesCache() @@ -53,17 +42,19 @@ namespace Umbraco.Tests.Routing public void Ensure_Cache_Is_Correct() { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; + SettingsForTests.AddTrailingSlash = false; // (cached routes have none) var samples = new Dictionary { { 1046, "/home" }, - { 1173, "/home/sub1/" }, - { 1174, "/home/sub1/sub2/" }, - { 1176, "/home/sub1/sub-3/" }, - { 1177, "/home/sub1/custom-sub-1/" }, - { 1178, "/home/sub1/custom-sub-2/" }, - { 1175, "/home/sub-2/" }, - { 1172, "/test-page/" } + { 1173, "/home/sub1" }, + { 1174, "/home/sub1/sub2" }, + { 1176, "/home/sub1/sub-3" }, + { 1177, "/home/sub1/custom-sub-1" }, + { 1178, "/home/sub1/custom-sub-2" }, + { 1175, "/home/sub-2" }, + { 1172, "/test-page" } }; foreach (var sample in samples) @@ -72,7 +63,7 @@ namespace Umbraco.Tests.Routing Assert.AreEqual(sample.Value, result); } - var randomSample = new KeyValuePair(1177, "/home/sub1/custom-sub-1/"); + var randomSample = new KeyValuePair(1177, "/home/sub1/custom-sub-1"); for (int i = 0; i < 5; i++) { var result = routingContext.NiceUrlProvider.GetNiceUrl(randomSample.Key); @@ -113,9 +104,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; + SettingsForTests.UseDomainPrefixes = false; var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId); Assert.AreEqual(niceUrlMatch, result); @@ -137,9 +128,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true"); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = true; + SettingsForTests.UseDomainPrefixes = false; var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId); Assert.AreEqual(niceUrlMatch, result); @@ -150,16 +141,16 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("http://example.com/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDomainPrefixes = false; Assert.AreEqual("/home/sub1/custom-sub-1/", routingContext.NiceUrlProvider.GetNiceUrl(1177)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true; + SettingsForTests.UseDomainPrefixes = true; Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", routingContext.NiceUrlProvider.GetNiceUrl(1177)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDomainPrefixes = false; routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true; Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", routingContext.NiceUrlProvider.GetNiceUrl(1177)); } @@ -169,14 +160,14 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("http://example.com/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDomainPrefixes = false; Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true; + SettingsForTests.UseDomainPrefixes = true; Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDomainPrefixes = false; routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true; Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999)); } diff --git a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs index f05818541b..03e9d31ee7 100644 --- a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs @@ -14,20 +14,11 @@ namespace Umbraco.Tests.Routing [TestFixture] public class NiceUrlsProviderWithDomainsTests : BaseRoutingTest { - public override void TearDown() - { - base.TearDown(); - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", ""); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", ""); - } - internal override IRoutesCache GetRoutesCache() { return new DefaultRoutesCache(false); } - void InitializeLanguagesAndDomains() { var domains = Domain.GetDomains(); @@ -195,9 +186,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; InitializeLanguagesAndDomains(); SetDomains1(); @@ -224,9 +215,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; InitializeLanguagesAndDomains(); SetDomains2(); @@ -245,9 +236,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; InitializeLanguagesAndDomains(); SetDomains3(); @@ -271,11 +262,11 @@ namespace Umbraco.Tests.Routing public void Get_Nice_Url_NestedDomains(int nodeId, string currentUrl, bool absolute, string expected) { var routingContext = GetRoutingContext("/test", 1111); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; + InitializeLanguagesAndDomains(); SetDomains4(); @@ -289,9 +280,9 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; InitializeLanguagesAndDomains(); SetDomains4(); @@ -348,22 +339,22 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("http://domain1.com/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; InitializeLanguagesAndDomains(); SetDomains4(); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; - Assert.AreEqual("/en/1001-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100111)); + SettingsForTests.UseDomainPrefixes = false; + Assert.AreEqual("/en/1001-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100111)); Assert.AreEqual("http://domain3.com/en/1003-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100311)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true; - Assert.AreEqual("http://domain1.com/en/1001-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100111)); + SettingsForTests.UseDomainPrefixes = true; + Assert.AreEqual("http://domain1.com/en/1001-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100111)); Assert.AreEqual("http://domain3.com/en/1003-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100311)); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; - routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true; + SettingsForTests.UseDomainPrefixes = false; + routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true; Assert.AreEqual("http://domain1.com/en/1001-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100111)); Assert.AreEqual("http://domain3.com/en/1003-1-1/", routingContext.NiceUrlProvider.GetNiceUrl(100311)); } @@ -373,8 +364,8 @@ namespace Umbraco.Tests.Routing { var routingContext = GetRoutingContext("http://domain1.com/test", 1111); - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; InitializeLanguagesAndDomains(); SetDomains5(); diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index b4f5d19ba6..3b828dca4b 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -20,7 +20,7 @@ namespace Umbraco.Tests.Routing public override void Initialize() { base.Initialize(); - System.Configuration.ConfigurationManager.AppSettings.Set("umbracoPath", "~/umbraco"); + SettingsForTests.UmbracoPath = "~/umbraco"; SurfaceControllerResolver.Current = new SurfaceControllerResolver( PluginManager.Current.ResolveSurfaceControllers()); @@ -36,7 +36,6 @@ namespace Umbraco.Tests.Routing { base.TearDown(); RouteTable.Routes.Clear(); - System.Configuration.ConfigurationManager.AppSettings.Set("umbracoPath", ""); SurfaceControllerResolver.Reset(); } diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs index c00e97eb15..3afee92761 100644 --- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs +++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs @@ -57,9 +57,9 @@ namespace Umbraco.Tests.Routing //create the module _module = new UmbracoModule(); - ConfigurationManager.AppSettings.Set("umbracoConfigurationStatus", Umbraco.Core.Configuration.GlobalSettings.CurrentVersion); - ConfigurationManager.AppSettings.Set("umbracoReservedPaths", "~/umbraco,~/install/"); - ConfigurationManager.AppSettings.Set("umbracoReservedUrls", "~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd"); + SettingsForTests.ConfigurationStatus = UmbracoVersion.Current.ToString(3); + SettingsForTests.ReservedPaths = "~/umbraco,~/install/"; + SettingsForTests.ReservedUrls = "~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd"; //create the not found handlers config using (var sw = File.CreateText(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemFiles.NotFoundhandlersConfig, false))) @@ -78,11 +78,6 @@ namespace Umbraco.Tests.Routing base.TearDown(); _module.DisposeIfDisposable(); - - //reset the app config - ConfigurationManager.AppSettings.Set("umbracoConfigurationStatus", ""); - ConfigurationManager.AppSettings.Set("umbracoReservedPaths", ""); - ConfigurationManager.AppSettings.Set("umbracoReservedUrls", ""); } // do not test for /base here as it's handled before EnsureUmbracoRoutablePage is called diff --git a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs index 17f5f190d2..858ef9c85b 100644 --- a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs +++ b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs @@ -22,9 +22,9 @@ namespace Umbraco.Tests.Routing [Test] public void DoNotPolluteCache() { - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains + SettingsForTests.UseDomainPrefixes = false; InitializeLanguagesAndDomains(); SetDomains1(); @@ -64,15 +64,6 @@ namespace Umbraco.Tests.Routing //Assert.AreEqual("http://domain1.com/1001-1/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111, true)); // bad } - public override void TearDown() - { - base.TearDown(); - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", ""); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", ""); - - } - internal override IRoutesCache GetRoutesCache() { return new DefaultRoutesCache(false); diff --git a/src/Umbraco.Tests/Routing/uQueryGetNodeIdByUrlTests.cs b/src/Umbraco.Tests/Routing/uQueryGetNodeIdByUrlTests.cs index 008c73e4c7..ab0aa6cb37 100644 --- a/src/Umbraco.Tests/Routing/uQueryGetNodeIdByUrlTests.cs +++ b/src/Umbraco.Tests/Routing/uQueryGetNodeIdByUrlTests.cs @@ -16,14 +16,6 @@ namespace Umbraco.Tests.Routing [TestFixture] public class uQueryGetNodeIdByUrlTests : BaseRoutingTest { - public override void TearDown() - { - base.TearDown(); - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", ""); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", ""); - } - internal override IRoutesCache GetRoutesCache() { return new DefaultRoutesCache(false); @@ -70,10 +62,9 @@ namespace Umbraco.Tests.Routing public void GetNodeIdByUrl_Not_Hiding_Top_Level_Absolute(int nodeId, string url) { - - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; + SettingsForTests.UseDomainPrefixes = false; Assert.AreEqual(nodeId, global::umbraco.uQuery.GetNodeIdByUrl("http://example.com" + url)); } @@ -89,9 +80,9 @@ namespace Umbraco.Tests.Routing public void GetNodeIdByUrl_Not_Hiding_Top_Level_Relative(int nodeId, string url) { - ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true"); - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); - Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false; + SettingsForTests.UseDirectoryUrls = true; + SettingsForTests.HideTopLevelNodeFromPath = false; + SettingsForTests.UseDomainPrefixes = false; Assert.AreEqual(nodeId, global::umbraco.uQuery.GetNodeIdByUrl(url)); } diff --git a/src/Umbraco.Tests/TestHelpers/BaseRoutingTest.cs b/src/Umbraco.Tests/TestHelpers/BaseRoutingTest.cs index 3cb5d42234..5144b37408 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseRoutingTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseRoutingTest.cs @@ -12,18 +12,6 @@ namespace Umbraco.Tests.TestHelpers [TestFixture, RequiresSTA] public abstract class BaseRoutingTest : BaseWebTest { - public override void Initialize() - { - base.Initialize(); - } - - public override void TearDown() - { - base.TearDown(); - - ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", ""); - } - /// /// Return a new RoutingContext /// diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs index 3a404347f0..757f83d9fc 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs @@ -23,7 +23,9 @@ namespace Umbraco.Tests.TestHelpers [SetUp] public virtual void Initialize() { - TestHelper.SetupLog4NetForTests(); + SettingsForTests.Reset(); + + TestHelper.SetupLog4NetForTests(); AppDomain.CurrentDomain.SetData("DataDirectory", TestHelper.CurrentAssemblyDirectory); @@ -52,7 +54,7 @@ namespace Umbraco.Tests.TestHelpers Cache.ClearAllCache(); - UmbracoSettings.ResetSetters(); + SettingsForTests.Reset(); } /// diff --git a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs new file mode 100644 index 0000000000..69525d361d --- /dev/null +++ b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Configuration; +using Umbraco.Core.Configuration; + +namespace Umbraco.Tests.TestHelpers +{ + class SettingsForTests + { + // umbracoSettings + + public static bool UseLegacyXmlSchema + { + get { return UmbracoSettings.UseLegacyXmlSchema; } + set { UmbracoSettings.UseLegacyXmlSchema = value; } + } + + public static bool AddTrailingSlash + { + get { return UmbracoSettings.AddTrailingSlash; } + set { UmbracoSettings.AddTrailingSlash = value; } + } + + public static bool UseDomainPrefixes + { + get { return UmbracoSettings.UseDomainPrefixes; } + set { UmbracoSettings.UseDomainPrefixes = value; } + } + + public static string SettingsFilePath + { + get { return UmbracoSettings.SettingsFilePath; } + set { UmbracoSettings.SettingsFilePath = value; } + } + + // from appSettings + + private static readonly IDictionary SavedAppSettings = new Dictionary(); + + static void SaveSetting(string key) + { + SavedAppSettings[key] = ConfigurationManager.AppSettings[key]; + } + + static void SaveSettings() + { + SaveSetting("umbracoHideTopLevelNodeFromPath"); + SaveSetting("umbracoUseDirectoryUrls"); + SaveSetting("umbracoPath"); + SaveSetting("umbracoReservedPaths"); + SaveSetting("umbracoReservedUrls"); + SaveSetting("umbracoConfigurationStatus"); + + SaveSetting(GlobalSettings.UmbracoConnectionName); + } + + public static bool HideTopLevelNodeFromPath + { + get { return GlobalSettings.HideTopLevelNodeFromPath; } + set { ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", value ? "true" : "false"); } + } + + public static bool UseDirectoryUrls + { + get { return GlobalSettings.UseDirectoryUrls; } + set { ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", value ? "true" : "false"); } + } + + public static string UmbracoPath + { + get { return GlobalSettings.Path; } + set { ConfigurationManager.AppSettings.Set("umbracoPath", value); } + } + + public static string ReservedPaths + { + get { return GlobalSettings.ReservedPaths; } + set { ConfigurationManager.AppSettings.Set("umbracoReservedPaths", value); } + } + + public static string ReservedUrls + { + get { return GlobalSettings.ReservedUrls; } + set { ConfigurationManager.AppSettings.Set("umbracoReservedUrls", value); } + } + + public static string ConfigurationStatus + { + get { return GlobalSettings.ConfigurationStatus; } + set { ConfigurationManager.AppSettings.Set("umbracoConfigurationStatus", value); } + } + + // reset & defaults + + static SettingsForTests() + { + SaveSettings(); + } + + public static void Reset() + { + UmbracoSettings.ResetSetters(); + + foreach (var kvp in SavedAppSettings) + ConfigurationManager.AppSettings.Set(kvp.Key, kvp.Value); + + // set some defaults that are wrong in the config file?! + // this is annoying, really + HideTopLevelNodeFromPath = false; + } + } +} diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 080ad615b0..e9c23eb182 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -97,6 +97,7 @@ + From 452a0a43b005916e07dfcef1cebba3f25f170c72 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Tue, 19 Feb 2013 20:57:20 -0100 Subject: [PATCH 07/18] Fixes U4-1561 V6.0 RC - Member Profile property saving doesn't work --- src/umbraco.providers/members/MembersProfileProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/umbraco.providers/members/MembersProfileProvider.cs b/src/umbraco.providers/members/MembersProfileProvider.cs index ef3f6c14e3..bd8f6a5ce7 100644 --- a/src/umbraco.providers/members/MembersProfileProvider.cs +++ b/src/umbraco.providers/members/MembersProfileProvider.cs @@ -153,7 +153,7 @@ namespace umbraco.providers.members { if (m.getProperty(spv.Name) != null) m.getProperty(spv.Name).Value = spv.PropertyValue; } - + m.Save(); } } } From 879c77c68de5839caf0753e9edca5e3cccbcb358 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Wed, 20 Feb 2013 07:07:57 +0600 Subject: [PATCH 08/18] Applies same try/catch logic for setup/teardown because I'm still experiencing issues with the SQLCE db file being locked which mucks up the rest of the setup/teardowns and tests fail. --- .../TestHelpers/BaseDatabaseFactoryTest.cs | 50 +++++++++++++------ .../TestHelpers/BaseDatabaseTest.cs | 18 ++++--- 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index 8fe77fa24b..c04cb06d7b 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -8,6 +8,7 @@ using NUnit.Framework; using SQLCE4Umbraco; using Umbraco.Core; using Umbraco.Core.Configuration; +using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.SqlSyntax; @@ -38,22 +39,32 @@ namespace Umbraco.Tests.TestHelpers string path = TestHelper.CurrentAssemblyDirectory; AppDomain.CurrentDomain.SetData("DataDirectory", path); - UmbracoSettings.UseLegacyXmlSchema = false; - - RepositoryResolver.Current = new RepositoryResolver( - new RepositoryFactory()); - //Ensure that any database connections from a previous test is disposed. This is really just double safety as its also done in the TearDown. if(ApplicationContext != null && DatabaseContext != null) DatabaseContext.Database.Dispose(); SqlCeContextGuardian.CloseBackgroundConnection(); - //Delete database file before continueing - string filePath = string.Concat(path, "\\UmbracoPetaPocoTests.sdf"); - if (File.Exists(filePath)) + try { - File.Delete(filePath); + //Delete database file before continueing + string filePath = string.Concat(path, "\\UmbracoPetaPocoTests.sdf"); + if (File.Exists(filePath)) + { + File.Delete(filePath); + } } + catch (Exception) + { + //if this doesn't work we have to make sure everything is reset! otherwise + // well run into issues because we've already set some things up + TearDown(); + throw; + } + + UmbracoSettings.UseLegacyXmlSchema = false; + + RepositoryResolver.Current = new RepositoryResolver( + new RepositoryFactory()); //Get the connectionstring settings from config var settings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName]; @@ -102,13 +113,24 @@ namespace Umbraco.Tests.TestHelpers string path = TestHelper.CurrentAssemblyDirectory; AppDomain.CurrentDomain.SetData("DataDirectory", null); - string filePath = string.Concat(path, "\\UmbracoPetaPocoTests.sdf"); - if (File.Exists(filePath)) - { - File.Delete(filePath); - } SettingsForTests.Reset(); UmbracoSettings.ResetSetters(); + + try + { + string filePath = string.Concat(path, "\\UmbracoPetaPocoTests.sdf"); + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + } + catch (Exception ex) + { + LogHelper.Error("Could not remove the old database file", ex); + + //We will swallow this exception! That's because a sub class might require further teardown logic. + } + } protected ApplicationContext ApplicationContext diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs index c541a3c5a7..763e105480 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs @@ -30,13 +30,10 @@ namespace Umbraco.Tests.TestHelpers TestHelper.SetupLog4NetForTests(); TestHelper.InitializeContentDirectories(); - UmbracoSettings.UseLegacyXmlSchema = false; - string path = TestHelper.CurrentAssemblyDirectory; AppDomain.CurrentDomain.SetData("DataDirectory", path); - //If the Database Provider is Sql Ce we need to ensure the database - if (ProviderName.Contains("SqlServerCe")) + try { //Delete database file before continueing string filePath = string.Concat(path, "\\test.sdf"); @@ -44,11 +41,16 @@ namespace Umbraco.Tests.TestHelpers { File.Delete(filePath); } - - //Create the Sql CE database - var engine = new SqlCeEngine(ConnectionString); - engine.CreateDatabase(); } + catch (Exception) + { + //if this doesn't work we have to make sure everything is reset! otherwise + // well run into issues because we've already set some things up + TearDown(); + throw; + } + + UmbracoSettings.UseLegacyXmlSchema = false; RepositoryResolver.Current = new RepositoryResolver( new RepositoryFactory()); From 5b0a8c06688f248769546adef005ff8e274a6183 Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 20 Feb 2013 10:12:41 -0100 Subject: [PATCH 09/18] Tests - fix build broken by back-porting 6.x code --- src/Umbraco.Tests/Routing/UmbracoModuleTests.cs | 2 +- src/Umbraco.Tests/TestHelpers/SettingsForTests.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs index 3afee92761..02cd000239 100644 --- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs +++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs @@ -57,7 +57,7 @@ namespace Umbraco.Tests.Routing //create the module _module = new UmbracoModule(); - SettingsForTests.ConfigurationStatus = UmbracoVersion.Current.ToString(3); + SettingsForTests.ConfigurationStatus = Core.Configuration.GlobalSettings.CurrentVersion; SettingsForTests.ReservedPaths = "~/umbraco,~/install/"; SettingsForTests.ReservedUrls = "~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd"; diff --git a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs index 69525d361d..cc7873afbf 100644 --- a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs +++ b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs @@ -52,8 +52,6 @@ namespace Umbraco.Tests.TestHelpers SaveSetting("umbracoReservedPaths"); SaveSetting("umbracoReservedUrls"); SaveSetting("umbracoConfigurationStatus"); - - SaveSetting(GlobalSettings.UmbracoConnectionName); } public static bool HideTopLevelNodeFromPath From e8524963ddf9f9b6f3d805883591c27208b9de95 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Wed, 20 Feb 2013 11:20:06 -0100 Subject: [PATCH 10/18] Fixes U4-1716 --- .../umbraco.presentation/umbraco/Trees/loadNodeTypes.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadNodeTypes.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadNodeTypes.cs index 8a0b143521..1dca0daa7d 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadNodeTypes.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadNodeTypes.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Text; using Umbraco.Core.Services; using umbraco.businesslogic; @@ -57,7 +58,7 @@ function openNodeType(id) { public override void Render(ref XmlTree tree) { - var docTypes = Service.GetContentTypeChildren(base.m_id); + var docTypes = Service.GetContentTypeChildren(base.m_id).OrderBy(x => x.Name); foreach (var docType in docTypes) { From b06620f56ebee860eb501f09b98e885582a24aa5 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 20 Feb 2013 14:34:18 -0100 Subject: [PATCH 11/18] Make the SQL Azure connection string support custom domains and all kinds of ways of entering it. --- src/Umbraco.Core/DatabaseContext.cs | 48 ++++++++++++++++++- .../Persistence/DatabaseContextTests.cs | 26 ++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs index 7ab6fa3490..90b62acfcd 100644 --- a/src/Umbraco.Core/DatabaseContext.cs +++ b/src/Umbraco.Core/DatabaseContext.cs @@ -158,7 +158,7 @@ namespace Umbraco.Core } else if (databaseProvider.ToLower().Contains("azure")) { - connectionString = string.Format("Server=tcp:{0}.database.windows.net;Database={1};User ID={2}@{0};Password={3}", server, databaseName, user, password); + connectionString = BuildAzureConnectionString(server, databaseName, user, password); } else { @@ -169,6 +169,52 @@ namespace Umbraco.Core Initialize(providerName); } + internal string BuildAzureConnectionString(string server, string databaseName, string user, string password) + { + if (server.Contains(".") && ServerStartsWithTcp(server) == false) + server = string.Format("tcp:{0}", server); + + if (server.Contains(".") == false && ServerStartsWithTcp(server)) + { + string serverName = server.Contains(",") + ? server.Substring(0, server.IndexOf(",", StringComparison.Ordinal)) + : server; + + var portAddition = string.Empty; + + if (server.Contains(",")) + portAddition = server.Substring(server.IndexOf(",", StringComparison.Ordinal)); + + server = string.Format("{0}.database.windows.net{1}", serverName, portAddition); + } + + if (ServerStartsWithTcp(server) == false) + server = string.Format("tcp:{0}.database.windows.net", server); + + if (server.Contains(",") == false) + server = string.Format("{0},1433", server); + + if (user.Contains("@") == false) + { + var userDomain = server; + + if (ServerStartsWithTcp(server)) + userDomain = userDomain.Substring(userDomain.IndexOf(":", StringComparison.Ordinal) + 1); + + if (userDomain.Contains(".")) + userDomain = userDomain.Substring(0, userDomain.IndexOf(".", StringComparison.Ordinal)); + + user = string.Format("{0}@{1}", user, userDomain); + } + + return string.Format("Server={0};Database={1};User ID={2};Password={3}", server, databaseName, user, password); + } + + private static bool ServerStartsWithTcp(string server) + { + return server.ToLower().StartsWith("tcp:".ToLower()); + } + /// /// Saves the connection string as a proper .net ConnectionString and the legacy AppSettings key/value. /// diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index acd2d7dfff..b5fc8bcc4b 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -88,5 +88,31 @@ namespace Umbraco.Tests.Persistence Assert.That(umbracoUserTable, Is.True); Assert.That(cmsTagsTable, Is.True); } + + [TestCase("MyServer", "MyDatabase", "MyUser", "MyPassword")] + [TestCase("MyServer", "MyDatabase", "MyUser@MyServer", "MyPassword")] + [TestCase("tcp:MyServer", "MyDatabase", "MyUser", "MyPassword")] + [TestCase("tcp:MyServer", "MyDatabase", "MyUser@MyServer", "MyPassword")] + [TestCase("tcp:MyServer,1433", "MyDatabase", "MyUser", "MyPassword")] + [TestCase("tcp:MyServer,1433", "MyDatabase", "MyUser@MyServer", "MyPassword")] + [TestCase("tcp:MyServer.database.windows.net", "MyDatabase", "MyUser", "MyPassword")] + [TestCase("tcp:MyServer.database.windows.net", "MyDatabase", "MyUser@MyServer", "MyPassword")] + [TestCase("tcp:MyServer.database.windows.net,1433", "MyDatabase", "MyUser", "MyPassword")] + [TestCase("tcp:MyServer.database.windows.net,1433", "MyDatabase", "MyUser@MyServer", "MyPassword")] + public void Build_Azure_Connection_String_Regular(string server, string databaseName, string userName, string password) + { + var connectionString = _dbContext.BuildAzureConnectionString(server, databaseName, userName, password); + Assert.AreEqual(connectionString, "Server=tcp:MyServer.database.windows.net,1433;Database=MyDatabase;User ID=MyUser@MyServer;Password=MyPassword"); + } + + [TestCase("tcp:kzeej5z8ty.ssmsawacluster4.windowsazure.mscds.com,1433", "MyDatabase", "MyUser", "MyPassword")] + [TestCase("tcp:kzeej5z8ty.ssmsawacluster4.windowsazure.mscds.com,1433", "MyDatabase", "MyUser@kzeej5z8ty", "MyPassword")] + [TestCase("tcp:kzeej5z8ty.ssmsawacluster4.windowsazure.mscds.com", "MyDatabase", "MyUser", "MyPassword")] + [TestCase("tcp:kzeej5z8ty.ssmsawacluster4.windowsazure.mscds.com", "MyDatabase", "MyUser@kzeej5z8ty", "MyPassword")] + public void Build_Azure_Connection_String_CustomServer(string server, string databaseName, string userName, string password) + { + var connectionString = _dbContext.BuildAzureConnectionString(server, databaseName, userName, password); + Assert.AreEqual(connectionString, "Server=tcp:kzeej5z8ty.ssmsawacluster4.windowsazure.mscds.com,1433;Database=MyDatabase;User ID=MyUser@kzeej5z8ty;Password=MyPassword"); + } } } \ No newline at end of file From e333ad2b237ee1b14540d873b3620856588dba09 Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 20 Feb 2013 14:38:28 -0100 Subject: [PATCH 12/18] Tests.Routing - fix tests --- src/SQLCE4Umbraco/SqlCEHelper.cs | 89 +++++++++++++++---- src/Umbraco.Tests/Models/ContentXmlTest.cs | 4 +- src/Umbraco.Tests/Models/MediaXmlTest.cs | 8 +- .../LookupByNiceUrlWithDomainsTests.cs | 6 +- .../NiceUrlsProviderWithDomainsTests.cs | 8 ++ .../Routing/UmbracoModuleTests.cs | 27 ------ .../Routing/UrlsWithNestedDomains.cs | 8 ++ src/Umbraco.Tests/TestHelpers/TestHelper.cs | 11 +++ 8 files changed, 112 insertions(+), 49 deletions(-) diff --git a/src/SQLCE4Umbraco/SqlCEHelper.cs b/src/SQLCE4Umbraco/SqlCEHelper.cs index c0a4c875b1..a35f84de82 100644 --- a/src/SQLCE4Umbraco/SqlCEHelper.cs +++ b/src/SQLCE4Umbraco/SqlCEHelper.cs @@ -50,35 +50,90 @@ namespace SqlCE4Umbraco /// internal void ClearDatabase() { + // drop constraints before tables to avoid exceptions + // looping on try/catching exceptions was not really nice + + // http://stackoverflow.com/questions/536350/drop-all-the-tables-stored-procedures-triggers-constriants-and-all-the-depend + var localConnection = new SqlCeConnection(ConnectionString); if (System.IO.File.Exists(ReplaceDataDirectory(localConnection.Database))) { - var tables = new List(); - using (var reader = ExecuteReader("select table_name from information_schema.tables where TABLE_TYPE <> 'VIEW'")) + List tables; + + // drop foreign keys + // SQL may need "where constraint_catalog=DB_NAME() and ..." + tables = new List(); + using (var reader = ExecuteReader("select table_name from information_schema.table_constraints where constraint_type = 'FOREIGN KEY' order by table_name")) { - while (reader.Read()) + while (reader.Read()) tables.Add(reader.GetString("table_name").Trim()); + } + + foreach (var table in tables) + { + var constraints = new List(); + using (var reader = ExecuteReader("select constraint_name from information_schema.table_constraints where constraint_type = 'FOREIGN KEY' and table_name = '" + table + "' order by constraint_name")) { - tables.Add(reader.GetString("TABLE_NAME")); + while (reader.Read()) constraints.Add(reader.GetString("constraint_name").Trim()); + } + foreach (var constraint in constraints) + { + // SQL may need "[dbo].[table]" + ExecuteNonQuery("alter table [" + table + "] drop constraint [" + constraint + "]"); } } - while(tables.Any()) + // drop primary keys + // SQL may need "where constraint_catalog=DB_NAME() and ..." + tables = new List(); + using (var reader = ExecuteReader("select table_name from information_schema.table_constraints where constraint_type = 'PRIMARY KEY' order by table_name")) { - for (var i = 0; i < tables.Count; i++) - { - var dropTable = "DROP TABLE " + tables[i]; + while (reader.Read()) tables.Add(reader.GetString("table_name").Trim()); + } - try - { - ExecuteNonQuery(dropTable); - tables.Remove(tables[i]); - } - catch (SqlHelperException ex) - { - //this will occur because there is no cascade option, so we just wanna try the next one - } + foreach (var table in tables) + { + var constraints = new List(); + using (var reader = ExecuteReader("select constraint_name from information_schema.table_constraints where constraint_type = 'PRIMARY KEY' and table_name = '" + table + "' order by constraint_name")) + { + while (reader.Read()) constraints.Add(reader.GetString("constraint_name").Trim()); + } + foreach (var constraint in constraints) + { + // SQL may need "[dbo].[table]" + ExecuteNonQuery("alter table [" + table + "] drop constraint [" + constraint + "]"); } } + + // drop tables + tables = new List(); + using (var reader = ExecuteReader("select table_name from information_schema.tables where table_type <> 'VIEW' order by table_name")) + { + while (reader.Read()) tables.Add(reader.GetString("table_name").Trim()); + } + + foreach (var table in tables) + { + ExecuteNonQuery("drop table [" + table + "]"); + } + } + } + + /// + /// Drops all foreign keys on a table. + /// + /// The name of the table. + /// To be used in unit tests. + internal void DropForeignKeys(string table) + { + var constraints = new List(); + using (var reader = ExecuteReader("select constraint_name from information_schema.table_constraints where constraint_type = 'FOREIGN KEY' and table_name = '" + table + "' order by constraint_name")) + { + while (reader.Read()) constraints.Add(reader.GetString("constraint_name").Trim()); + } + foreach (var constraint in constraints) + { + // SQL may need "[dbo].[table]" + ExecuteNonQuery("alter table [" + table + "] drop constraint [" + constraint + "]"); } } diff --git a/src/Umbraco.Tests/Models/ContentXmlTest.cs b/src/Umbraco.Tests/Models/ContentXmlTest.cs index 38f75bf9c6..4f820dd4e2 100644 --- a/src/Umbraco.Tests/Models/ContentXmlTest.cs +++ b/src/Umbraco.Tests/Models/ContentXmlTest.cs @@ -35,10 +35,10 @@ namespace Umbraco.Tests.Models [TearDown] public override void TearDown() { + base.TearDown(); + //reset the app context DataTypesResolver.Reset(); - - base.TearDown(); } [Test] public void Can_Generate_Xml_Representation_Of_Content() diff --git a/src/Umbraco.Tests/Models/MediaXmlTest.cs b/src/Umbraco.Tests/Models/MediaXmlTest.cs index ff7756b804..773a7ad09a 100644 --- a/src/Umbraco.Tests/Models/MediaXmlTest.cs +++ b/src/Umbraco.Tests/Models/MediaXmlTest.cs @@ -2,6 +2,7 @@ using System.Xml.Linq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.ObjectResolution; using Umbraco.Core.Models; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; @@ -16,6 +17,8 @@ namespace Umbraco.Tests.Models [SetUp] public override void Initialize() { + Resolution.IsFrozen = false; + //this ensures its reset PluginManager.Current = new PluginManager(); @@ -26,6 +29,7 @@ namespace Umbraco.Tests.Models typeof(tinyMCE3dataType).Assembly }; + DataTypesResolver.Reset(); DataTypesResolver.Current = new DataTypesResolver( () => PluginManager.Current.ResolveDataTypes()); @@ -35,10 +39,10 @@ namespace Umbraco.Tests.Models [TearDown] public override void TearDown() { + base.TearDown(); + //reset the app context DataTypesResolver.Reset(); - - base.TearDown(); } [Test] public void Can_Generate_Xml_Representation_Of_Media() diff --git a/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs b/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs index 0fe5b1f679..1b75ee81d5 100644 --- a/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs @@ -17,7 +17,11 @@ namespace Umbraco.Tests.Routing public override void Initialize() { base.Initialize(); - InitializeLanguagesAndDomains(); + + // ensure we can create them although the content is not in the database + TestHelper.DropForeignKeys("umbracoDomains"); + + InitializeLanguagesAndDomains(); } void InitializeLanguagesAndDomains() diff --git a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs index 03e9d31ee7..28752762a7 100644 --- a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs @@ -14,6 +14,14 @@ namespace Umbraco.Tests.Routing [TestFixture] public class NiceUrlsProviderWithDomainsTests : BaseRoutingTest { + public override void Initialize() + { + base.Initialize(); + + // ensure we can create them although the content is not in the database + TestHelper.DropForeignKeys("umbracoDomains"); + } + internal override IRoutesCache GetRoutesCache() { return new DefaultRoutesCache(false); diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs index 34aec56aed..5e7e47fc71 100644 --- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs +++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs @@ -16,33 +16,6 @@ using umbraco.cms.businesslogic.template; namespace Umbraco.Tests.Routing { - [TestFixture, RequiresSTA] - public class PublishedContentRequestBuilderTests : BaseRoutingTest - { - - //[Test] - //public void Alt_Template() - //{ - // var template = Template.MakeNew("test", new User(0)); - // var altTemplate = Template.MakeNew("alt", new User(0)); - // var umbracoContext = GetUmbracoContext("/home?altTemplate=" + altTemplate.Alias, template.Id); - // // create the new document request since we're rendering a document on the front-end - // var docreq = PublishedContentRequest.CreateForFrontEndRequest(umbracoContext); - - // //create the searcher - // var searcher = new PublishedContentRequestBuilder(docreq); - // //find domain - // searcher.LookupDomain(); - // // redirect if it has been flagged - // Assert.IsFalse(docreq.IsRedirect); - - // //find the document, found will be true if the doc request has found BOTH a node and a template - // var found = searcher.LookupDocument(); - - //} - - } - [TestFixture, RequiresSTA] public class UmbracoModuleTests : BaseRoutingTest { diff --git a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs index 858ef9c85b..515263eef6 100644 --- a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs +++ b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs @@ -64,6 +64,14 @@ namespace Umbraco.Tests.Routing //Assert.AreEqual("http://domain1.com/1001-1/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111, true)); // bad } + public override void Initialize() + { + base.Initialize(); + + // ensure we can create them although the content is not in the database + TestHelper.DropForeignKeys("umbracoDomains"); + } + internal override IRoutesCache GetRoutesCache() { return new DefaultRoutesCache(false); diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index 819ccdb68b..6ab161a3b0 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -31,6 +31,17 @@ namespace Umbraco.Tests.TestHelpers dataHelper.ClearDatabase(); } + public static void DropForeignKeys(string table) + { + var databaseSettings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName]; + var dataHelper = DataLayerHelper.CreateSqlHelper(databaseSettings.ConnectionString, false) as SqlCEHelper; + + if (dataHelper == null) + throw new InvalidOperationException("The sql helper for unit tests must be of type SqlCEHelper, check the ensure the connection string used for this test is set to use SQLCE"); + + dataHelper.DropForeignKeys(table); + } + /// /// Initializes a new database /// From 4201286038eac66b8eb9bf4741d87d36661a3ffa Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 20 Feb 2013 15:03:43 -0100 Subject: [PATCH 13/18] Don't check for database.windows.net to determine SQL Azure as WebPI sets a custom server name --- src/Umbraco.Core/DatabaseContext.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs index 90b62acfcd..597e4de24e 100644 --- a/src/Umbraco.Core/DatabaseContext.cs +++ b/src/Umbraco.Core/DatabaseContext.cs @@ -300,8 +300,7 @@ namespace Umbraco.Core { ConfigureEmbeddedDatabaseConnection(); } - else if (legacyConnString.ToLowerInvariant().Contains("database.windows.net") && - legacyConnString.ToLowerInvariant().Contains("tcp:")) + else if (legacyConnString.ToLowerInvariant().Contains("tcp:")) { //Must be sql azure SaveConnectionString(legacyConnString, "System.Data.SqlClient"); From bc824ba66aa5e1785f6d76c0ccb5a18155bc2ec4 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 20 Feb 2013 15:55:39 -0100 Subject: [PATCH 14/18] Updates for WebPI testers: Check if SQL CE file exists when connectionstring is filled in, make sure the connection string exists in web.config and if it has empty values, run the installer instead of trying to start the site. Also never claim the database is configure when the providername is empty. --- src/Umbraco.Core/DatabaseContext.cs | 3 +- src/Umbraco.Web.UI/web.Template.config | 6 +++- .../install/steps/database.ascx.cs | 31 ++++++++++--------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs index 597e4de24e..0acf98f842 100644 --- a/src/Umbraco.Core/DatabaseContext.cs +++ b/src/Umbraco.Core/DatabaseContext.cs @@ -278,7 +278,8 @@ namespace Umbraco.Core /// internal void Initialize() { - if (ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName] != null) + var databaseSettings = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName]; + if (databaseSettings != null && string.IsNullOrWhiteSpace(databaseSettings.ConnectionString) == false && string.IsNullOrWhiteSpace(databaseSettings.ProviderName) == false) { var providerName = "System.Data.SqlClient"; if (!string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName)) diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index d83c0e0cef..4702427a8f 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -79,7 +79,11 @@ - + + + + + diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/database.ascx.cs b/src/Umbraco.Web/umbraco.presentation/install/steps/database.ascx.cs index 8a57ad3b92..7d88678b05 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/steps/database.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/database.ascx.cs @@ -73,13 +73,17 @@ namespace umbraco.presentation.install.steps if (settings.Visible && !Page.IsPostBack) { //If the connection string is already present in web.config we don't need to show the settings page and we jump to installing/upgrading. - if ( - ConfigurationManager.ConnectionStrings[ - Umbraco.Core.Configuration.GlobalSettings.UmbracoConnectionName] == null - || - string.IsNullOrEmpty( - ConfigurationManager.ConnectionStrings[ - Umbraco.Core.Configuration.GlobalSettings.UmbracoConnectionName].ConnectionString)) + var databaseSettings = ConfigurationManager.ConnectionStrings[Umbraco.Core.Configuration.GlobalSettings.UmbracoConnectionName]; + + var dbIsSqlCe = databaseSettings.ProviderName == "System.Data.SqlServerCe.4.0"; + var sqlCeDatabaseExists = false; + if (dbIsSqlCe) + sqlCeDatabaseExists = File.Exists(databaseSettings.ConnectionString.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory").ToString())); + + // Either the connection details are not fully specified or it's a SQL CE database that doesn't exist yet + if (databaseSettings == null + || string.IsNullOrWhiteSpace(databaseSettings.ConnectionString) || string.IsNullOrWhiteSpace(databaseSettings.ProviderName) + || (dbIsSqlCe && sqlCeDatabaseExists == false)) { installProgress.Visible = true; upgradeProgress.Visible = false; @@ -115,20 +119,20 @@ namespace umbraco.presentation.install.steps protected void ShowDatabaseSettings() { // Parse the connection string - DbConnectionStringBuilder connectionStringBuilder = new DbConnectionStringBuilder(); + var connectionStringBuilder = new DbConnectionStringBuilder(); var databaseSettings = ConfigurationManager.ConnectionStrings[Umbraco.Core.Configuration.GlobalSettings.UmbracoConnectionName]; - if (databaseSettings != null) + if (databaseSettings != null && string.IsNullOrWhiteSpace(databaseSettings.ConnectionString) == false) { var dataHelper = DataLayerHelper.CreateSqlHelper(databaseSettings.ConnectionString, false); connectionStringBuilder.ConnectionString = dataHelper.ConnectionString; // Prepare data layer type - string datalayerType = GetConnectionStringValue(connectionStringBuilder, "datalayer"); + var datalayerType = GetConnectionStringValue(connectionStringBuilder, "datalayer"); if (datalayerType.Length > 0) { foreach (ListItem item in DatabaseType.Items) - if (item.Value != String.Empty && datalayerType.Contains(item.Value)) + if (item.Value != string.Empty && datalayerType.Contains(item.Value)) DatabaseType.SelectedValue = item.Value; } else if (dataHelper.ConnectionString != "server=.\\SQLEXPRESS;database=DATABASE;user id=USER;password=PASS") @@ -138,7 +142,7 @@ namespace umbraco.presentation.install.steps { DatabaseType.SelectedValue = "SqlServer"; } - + DatabaseType_SelectedIndexChanged(this, new EventArgs()); // Prepare other fields @@ -154,8 +158,7 @@ namespace umbraco.presentation.install.steps toggleVisible(DatabaseUsernameItem, !ManualConnectionString && !IsEmbeddedDatabase); toggleVisible(DatabasePasswordItem, !ManualConnectionString && !IsEmbeddedDatabase); toggleVisible(DatabaseNameItem, !ManualConnectionString && !IsEmbeddedDatabase); - - + if (IsEmbeddedDatabase) dbinit.Text = "$('#databaseOptionEmbedded').click();$('#databaseOptionEmbedded').change();"; else if (ManualConnectionString) From d4fc82dae17ead80bfb07db02e757c4e254d638a Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 20 Feb 2013 18:28:07 -0100 Subject: [PATCH 15/18] Calculate the hash of the WebPI package so it's not such a manual process. --- build/Build.proj | 49 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/build/Build.proj b/build/Build.proj index e5c0116e15..5d30795763 100644 --- a/build/Build.proj +++ b/build/Build.proj @@ -1,3 +1,4 @@ + - + + + + + + + + + From d622f763938669d8e9d99ddffc9d354b2585a224 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Thu, 21 Feb 2013 05:02:06 +0600 Subject: [PATCH 16/18] Fixed #U4-814 and got all possible unit tests that were not working for DynamicNode but were working for DynamicPublishedContent working. --- .../DynamicDocumentTestsBase.cs | 56 ++++--- .../PublishedContent/DynamicNodeTests.cs | 21 +++ .../RazorDynamicNode/DynamicNode.cs | 155 ++++++++++++------ 3 files changed, 160 insertions(+), 72 deletions(-) diff --git a/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs b/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs index 591510d1ce..82b2a672e1 100644 --- a/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs +++ b/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs @@ -199,7 +199,7 @@ namespace Umbraco.Tests.PublishedContent Assert.AreEqual(4444, result.Id); } - [Ignore] + [Ignore("We are ignoring this test because currently our ExpressionParser class cannot deal with this... it needs some serious TLC but it is very complex.")] [Test] public void Complex_Linq() { @@ -229,43 +229,55 @@ namespace Umbraco.Tests.PublishedContent Assert.AreEqual(3, doc.Index()); } - [Ignore] [Test] - public void Is_First() + public virtual void Is_First_Root_Nodes() { var doc = GetDynamicNode(1046); //test root nodes Assert.IsTrue(doc.IsFirst()); doc = GetDynamicNode(1172); - Assert.IsFalse(doc.IsFirst()); - doc = GetDynamicNode(1173); //test normal nodes - Assert.IsTrue(doc.IsFirst()); - doc = GetDynamicNode(1175); - Assert.IsFalse(doc.IsFirst()); + Assert.IsFalse(doc.IsFirst()); } - [Ignore] + [Test] + public void Is_First() + { + var doc = GetDynamicNode(1173); //test normal nodes + Assert.IsTrue(doc.IsFirst()); + doc = GetDynamicNode(1175); + Assert.IsFalse(doc.IsFirst()); + } + + [Test] + public virtual void Is_Not_First_Root_Nodes() + { + var doc = GetDynamicNode(1046); //test root nodes + Assert.IsFalse(doc.IsNotFirst()); + doc = GetDynamicNode(1172); + Assert.IsTrue(doc.IsNotFirst()); + } + [Test] public void Is_Not_First() - { - var doc = GetDynamicNode(1046); //test root nodes - Assert.IsFalse(doc.IsNotFirst()); - doc = GetDynamicNode(1172); - Assert.IsTrue(doc.IsNotFirst()); - doc = GetDynamicNode(1173); //test normal nodes + { + var doc = GetDynamicNode(1173); //test normal nodes Assert.IsFalse(doc.IsNotFirst()); doc = GetDynamicNode(1175); Assert.IsTrue(doc.IsNotFirst()); } - [Ignore] + [Test] + public virtual void Is_Position_Root_Nodes() + { + var doc = GetDynamicNode(1046); //test root nodes + Assert.IsTrue(doc.IsPosition(0)); + doc = GetDynamicNode(1172); + Assert.IsTrue(doc.IsPosition(1)); + } + [Test] public void Is_Position() { - var doc = GetDynamicNode(1046); //test root nodes - Assert.IsTrue(doc.IsPosition(0)); - doc = GetDynamicNode(1172); - Assert.IsTrue(doc.IsPosition(1)); - doc = GetDynamicNode(1173); //test normal nodes + var doc = GetDynamicNode(1173); //test normal nodes Assert.IsTrue(doc.IsPosition(0)); doc = GetDynamicNode(1175); Assert.IsTrue(doc.IsPosition(1)); @@ -446,7 +458,6 @@ namespace Umbraco.Tests.PublishedContent Assert.AreEqual("Custom data with same property name as the member name", asDynamic.GetPropertyValue("CreatorName")); } - [Ignore] [Test] public void GetPropertyValue_Reflected() { @@ -467,7 +478,6 @@ namespace Umbraco.Tests.PublishedContent Assert.AreEqual("admin", asDynamic.CreatorName); } - [Ignore] [Test] public void Get_Member_Property() { diff --git a/src/Umbraco.Tests/PublishedContent/DynamicNodeTests.cs b/src/Umbraco.Tests/PublishedContent/DynamicNodeTests.cs index 038556a57a..68bca138c2 100644 --- a/src/Umbraco.Tests/PublishedContent/DynamicNodeTests.cs +++ b/src/Umbraco.Tests/PublishedContent/DynamicNodeTests.cs @@ -54,6 +54,27 @@ namespace Umbraco.Tests.PublishedContent } + [Test] + [Ignore("This test will never work unless DynamicNode is refactored a lot in order to get a list of root nodes since root nodes don't have a parent to look up")] + public override void Is_First_Root_Nodes() + { + base.Is_First_Root_Nodes(); + } + + [Test] + [Ignore("This test will never work unless DynamicNode is refactored a lot in order to get a list of root nodes since root nodes don't have a parent to look up")] + public override void Is_Not_First_Root_Nodes() + { + base.Is_Not_First_Root_Nodes(); + } + + [Test] + [Ignore("This test will never work unless DynamicNode is refactored a lot in order to get a list of root nodes since root nodes don't have a parent to look up")] + public override void Is_Position_Root_Nodes() + { + base.Is_Position_Root_Nodes(); + } + public override void TearDown() { base.TearDown(); diff --git a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs index 79f6f69c51..e7a03abd26 100644 --- a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs +++ b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs @@ -491,13 +491,25 @@ namespace umbraco.MacroEngines result = null; //this will never be returned - if (name == "ChildrenAsList" || name == "Children") + if (name.InvariantEquals("ChildrenAsList") || name.InvariantEquals("Children")) { result = GetChildrenAsList; //cache the result so we don't have to re-process the whole thing _cachedMemberOutput.TryAdd(name, result); return true; } + if (binder.Name.InvariantEquals("parentId")) + { + var parent = n.Parent; + if (parent == null) + { + throw new InvalidOperationException(string.Format("The node {0} does not have a parent", Id)); + } + result = parent.Id; + _cachedMemberOutput.TryAdd(name, result); + return true; + } + bool propertyExists = false; if (n != null) { @@ -609,24 +621,16 @@ namespace umbraco.MacroEngines } - try + //lookup the property using reflection + + result = GetReflectedProperty(binder.Name); + + if (result != null) { - result = n.GetType().InvokeMember(binder.Name, - System.Reflection.BindingFlags.GetProperty | - System.Reflection.BindingFlags.Instance | - System.Reflection.BindingFlags.Public, - null, - n, - null); - //cache the result so we don't have to re-process the whole thing - _cachedMemberOutput.TryAdd(name, result); + _cachedMemberOutput.TryAdd(name, result); return true; } - catch - { - //result = null; - //return false; - } + } //if property access, type lookup and member invoke all failed @@ -644,6 +648,42 @@ namespace umbraco.MacroEngines } return true; } + + private object GetReflectedProperty(string alias) + { + Func> getMember = + memberAlias => + { + try + { + return new Attempt(true, + n.GetType().InvokeMember(memberAlias, + System.Reflection.BindingFlags.GetProperty | + System.Reflection.BindingFlags.Instance | + System.Reflection.BindingFlags.Public, + null, + n, + null)); + } + catch (MissingMethodException ex) + { + return new Attempt(ex); + } + }; + + //try with the current casing + var attempt = getMember(alias); + if (!attempt.Success) + { + //if we cannot get with the current alias, try changing it's case + attempt = alias[0].IsUpperCase() + ? getMember(alias.ConvertCase(StringAliasCaseType.CamelCase)) + : getMember(alias.ConvertCase(StringAliasCaseType.PascalCase)); + } + + return attempt.Success ? attempt.Result : null; + } + private bool TryCreateInstanceRazorDataTypeModel(Guid dataType, Type dataTypeType, string value, out object result) { IRazorDataTypeModel razorDataTypeModel = Activator.CreateInstance(dataTypeType, false) as IRazorDataTypeModel; @@ -1333,13 +1373,25 @@ namespace umbraco.MacroEngines } public string GetPropertyValue(string alias, string fallback) { - var prop = GetProperty(alias); - if (prop != null) return prop.Value; - return fallback; + string prop; + if (alias.StartsWith("@")) + { + var p = GetReflectedProperty(alias.TrimStart('@')); + prop = p == null ? null : p.ToString(); + } + else + { + var p = GetProperty(alias); + prop = p != null ? p.Value : null; + } + return !prop.IsNullOrWhiteSpace() ? prop : fallback; } public string GetPropertyValue(string alias, bool recursive) { - return GetPropertyValue(alias, recursive, null); + var p = alias.StartsWith("@") + ? GetReflectedProperty(alias.TrimStart('@')) + : GetPropertyValue(alias, recursive, null); + return (string) p; } public string GetPropertyValue(string alias, bool recursive, string fallback) { @@ -1398,14 +1450,24 @@ namespace umbraco.MacroEngines { return this.Index(); } - public int Index() + + /// + /// Checks if the owner list is null and attempts to create it if there is a parent. + /// + /// Successful if the owners list is not null, false if the owners list could not be created and remains null + private bool EnsureOwnersList() { if (this.ownerList == null && this.Parent != null) { var list = this.Parent.ChildrenAsList.Select(n => new DynamicNode(n)); - this.ownerList = new DynamicNodeList(list); + this.ownerList = new DynamicNodeList(list); } - if (this.ownerList != null) + return this.ownerList != null; + } + + public int Index() + { + if (EnsureOwnersList()) { List container = this.ownerList.Items.ToList(); int currentIndex = container.FindIndex(n => n.Id == this.Id); @@ -1413,16 +1475,11 @@ namespace umbraco.MacroEngines { return currentIndex; } - else - { - throw new IndexOutOfRangeException(string.Format("Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list", this.Id)); - } - } - else - { - throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", this.Id)); + throw new IndexOutOfRangeException(string.Format("Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list", this.Id)); } + throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", this.Id)); } + public bool IsFirst() { return IsHelper(n => n.Index() == 0); @@ -1449,7 +1506,7 @@ namespace umbraco.MacroEngines } public bool IsPosition(int index) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1457,7 +1514,7 @@ namespace umbraco.MacroEngines } public HtmlString IsPosition(int index, string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1465,7 +1522,7 @@ namespace umbraco.MacroEngines } public HtmlString IsPosition(int index, string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } @@ -1473,7 +1530,7 @@ namespace umbraco.MacroEngines } public bool IsModZero(int modulus) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1481,7 +1538,7 @@ namespace umbraco.MacroEngines } public HtmlString IsModZero(int modulus, string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1489,7 +1546,7 @@ namespace umbraco.MacroEngines } public HtmlString IsModZero(int modulus, string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } @@ -1498,7 +1555,7 @@ namespace umbraco.MacroEngines public bool IsNotModZero(int modulus) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1506,7 +1563,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotModZero(int modulus, string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1514,7 +1571,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotModZero(int modulus, string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } @@ -1522,7 +1579,7 @@ namespace umbraco.MacroEngines } public bool IsNotPosition(int index) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1530,7 +1587,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotPosition(int index, string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1538,7 +1595,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotPosition(int index, string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } @@ -1546,7 +1603,7 @@ namespace umbraco.MacroEngines } public bool IsLast() { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1555,7 +1612,7 @@ namespace umbraco.MacroEngines } public HtmlString IsLast(string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1564,7 +1621,7 @@ namespace umbraco.MacroEngines } public HtmlString IsLast(string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } @@ -1573,7 +1630,7 @@ namespace umbraco.MacroEngines } public bool IsNotLast() { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1582,7 +1639,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotLast(string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1591,7 +1648,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotLast(string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } From f2d105d8b998854969da649c1b5fbdabcf2df868 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Thu, 21 Feb 2013 05:44:44 +0600 Subject: [PATCH 17/18] Fixed #U4-814 and got all possible unit tests that were not working for DynamicNode but were working for DynamicPublishedContent working. And fixed up the DynamicPublishedContent unit tests as these weren't working at all... but seemed to say they did on the build server. strange. --- .../DynamicDocumentTestsBase.cs | 1031 +++++++++-------- .../PublishedContent/DynamicNodeTests.cs | 21 + .../DynamicPublishedContentTests.cs | 4 + .../RazorDynamicNode/DynamicNode.cs | 626 +++++----- 4 files changed, 869 insertions(+), 813 deletions(-) diff --git a/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs b/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs index bb1e2e42ec..fc63ef4c39 100644 --- a/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs +++ b/src/Umbraco.Tests/PublishedContent/DynamicDocumentTestsBase.cs @@ -10,28 +10,28 @@ using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.PublishedContent { - [TestFixture] - public abstract class DynamicDocumentTestsBase : BaseRoutingTest - { - public override void Initialize() - { - base.Initialize(); - } + [TestFixture] + public abstract class DynamicDocumentTestsBase : BaseRoutingTest + { + public override void Initialize() + { + base.Initialize(); + } - public override void TearDown() - { - base.TearDown(); - - } + public override void TearDown() + { + base.TearDown(); - protected override bool RequiresDbSetup - { - get { return false; } - } + } - protected override string GetXmlContent(int templateId) - { - return @" + protected override bool RequiresDbSetup + { + get { return false; } + } + + protected override string GetXmlContent(int templateId) + { + return @" @@ -68,578 +68,587 @@ namespace Umbraco.Tests.PublishedContent "; - } + } - /// - /// Returns the dynamic node/document to run tests against - /// - /// - /// - protected abstract dynamic GetDynamicNode(int id); + /// + /// Returns the dynamic node/document to run tests against + /// + /// + /// + protected abstract dynamic GetDynamicNode(int id); - [Test] - public void Single() - { - var doc = GetDynamicNode(4444); + [Test] + public void Single() + { + var doc = GetDynamicNode(4444); - var result = doc.Children().Single(); + var result = doc.Children().Single(); - Assert.IsNotNull(result); - Assert.AreEqual(5555, result.Id); - } + Assert.IsNotNull(result); + Assert.AreEqual(5555, result.Id); + } - [Test] - public void Single_With_Query() - { - var doc = GetDynamicNode(1046); + [Test] + public void Single_With_Query() + { + var doc = GetDynamicNode(1046); - var result = doc.Children().Single("id==1175"); + var result = doc.Children().Single("id==1175"); - Assert.IsNotNull(result); - Assert.AreEqual(1175, result.Id); - } + Assert.IsNotNull(result); + Assert.AreEqual(1175, result.Id); + } - [Test] - public void First() - { - var doc = GetDynamicNode(1173); + [Test] + public void First() + { + var doc = GetDynamicNode(1173); - var result = doc.Children().First(); + var result = doc.Children().First(); - Assert.IsNotNull(result); - Assert.AreEqual(1174, result.Id); - } + Assert.IsNotNull(result); + Assert.AreEqual(1174, result.Id); + } - [Test] - public void First_With_Query() - { - var doc = GetDynamicNode(1173); + [Test] + public void First_With_Query() + { + var doc = GetDynamicNode(1173); - var result = doc.Children().First("blah==\"some content\""); + var result = doc.Children().First("blah==\"some content\""); - Assert.IsNotNull(result); - Assert.AreEqual(1176, result.Id); - } + Assert.IsNotNull(result); + Assert.AreEqual(1176, result.Id); + } - [Test] - public void Where_User_Property_Value() - { - var doc = GetDynamicNode(1173); + [Test] + public void Where_User_Property_Value() + { + var doc = GetDynamicNode(1173); - var result = (IEnumerable)doc.Children().Where("blah==\"some content\""); + var result = (IEnumerable)doc.Children().Where("blah==\"some content\""); - Assert.IsNotNull(result); - Assert.AreEqual(1, result.Count()); - Assert.AreEqual(1176, result.Single().Id); - } + Assert.IsNotNull(result); + Assert.AreEqual(1, result.Count()); + Assert.AreEqual(1176, result.Single().Id); + } - [Test] - public void String_ContainsValue_Extension_Method() - { - var doc = GetDynamicNode(1046); + [Test] + public void String_ContainsValue_Extension_Method() + { + var doc = GetDynamicNode(1046); - var paramVals = new Dictionary { { "searchId", 1173 } }; //this is an integer value - var result = doc.Children() - .Where("selectedNodes.ContainsValue(searchId)", paramVals) //call an extension method - .FirstOrDefault(); + var paramVals = new Dictionary { { "searchId", 1173 } }; //this is an integer value + var result = doc.Children() + .Where("selectedNodes.ContainsValue(searchId)", paramVals) //call an extension method + .FirstOrDefault(); - Assert.IsNotNull(result); - Assert.AreEqual(4444, result.Id); + Assert.IsNotNull(result); + Assert.AreEqual(4444, result.Id); - //don't find! - paramVals = new Dictionary { { "searchId", 1111777 } }; - result = doc.Children() - .Where("selectedNodes.ContainsValue(searchId)", paramVals) - .FirstOrDefault(); + //don't find! + paramVals = new Dictionary { { "searchId", 1111777 } }; + result = doc.Children() + .Where("selectedNodes.ContainsValue(searchId)", paramVals) + .FirstOrDefault(); - Assert.IsNotNull(result); - Assert.IsTrue(result.GetType() == typeof(DynamicNull) || result.GetType() == typeof(umbraco.MacroEngines.DynamicNull)); - //Assert.AreEqual(typeof(DynamicNull), result.GetType()); - } + Assert.IsNotNull(result); + Assert.IsTrue(result.GetType() == typeof(DynamicNull) || result.GetType() == typeof(umbraco.MacroEngines.DynamicNull)); + //Assert.AreEqual(typeof(DynamicNull), result.GetType()); + } - [Test] - public void String_Contains_Method() - { - var doc = GetDynamicNode(1046); + [Test] + public void String_Contains_Method() + { + var doc = GetDynamicNode(1046); - var paramVals = new Dictionary { { "searchId", "1173" } }; - var result = doc.Children() - .Where("selectedNodes.Contains(searchId)", paramVals) - .FirstOrDefault(); + var paramVals = new Dictionary { { "searchId", "1173" } }; + var result = doc.Children() + .Where("selectedNodes.Contains(searchId)", paramVals) + .FirstOrDefault(); - Assert.IsNotNull(result); - Assert.AreEqual(4444, result.Id); + Assert.IsNotNull(result); + Assert.AreEqual(4444, result.Id); - //don't find! - paramVals = new Dictionary { { "searchId", "1aaa173" } }; - result = doc.Children() - .Where("selectedNodes.Contains(searchId)", paramVals) - .FirstOrDefault(); + //don't find! + paramVals = new Dictionary { { "searchId", "1aaa173" } }; + result = doc.Children() + .Where("selectedNodes.Contains(searchId)", paramVals) + .FirstOrDefault(); - Assert.IsNotNull(result); - Assert.IsTrue(result.GetType() == typeof (DynamicNull) || result.GetType() == typeof (umbraco.MacroEngines.DynamicNull)); - //Assert.AreEqual(typeof (DynamicNull), result.GetType()); - } + Assert.IsNotNull(result); + Assert.IsTrue(result.GetType() == typeof(DynamicNull) || result.GetType() == typeof(umbraco.MacroEngines.DynamicNull)); + //Assert.AreEqual(typeof (DynamicNull), result.GetType()); + } - [Test] - public void String_Split_Method() - { - var doc = GetDynamicNode(1046); + [Test] + public void String_Split_Method() + { + var doc = GetDynamicNode(1046); - var paramVals = new Dictionary + var paramVals = new Dictionary { { "splitTerm", new char[] { ',' } }, { "splitOptions", StringSplitOptions.RemoveEmptyEntries } }; - var result = doc.Children() - .Where("selectedNodes.Split(splitTerm, splitOptions).Length == 3", paramVals) - .FirstOrDefault(); - - Assert.IsNotNull(result); - Assert.AreEqual(4444, result.Id); - } - - [Ignore] - [Test] - public void Complex_Linq() - { - var doc = GetDynamicNode(1173); - - var paramVals = new Dictionary {{"splitTerm", new char[] {','}}, {"searchId", "1173"}}; - var result = doc.Ancestors().OrderBy("level") - .Single() - .Descendants() - .Where("selectedNodes != null && selectedNodes != String.Empty && selectedNodes.Split(splitTerm).Contains(searchId)", paramVals) - .FirstOrDefault(); - - Assert.IsNotNull(result); - Assert.AreEqual(4444, result.Id); - } - - [Test] - public void Index() - { - var doc = GetDynamicNode(1173); - Assert.AreEqual(0, doc.Index()); - doc = GetDynamicNode(1176); - Assert.AreEqual(1, doc.Index()); - doc = GetDynamicNode(1177); - Assert.AreEqual(2, doc.Index()); - doc = GetDynamicNode(1178); - Assert.AreEqual(3, doc.Index()); - } - - [Ignore] - [Test] - public void Is_First() - { - var doc = GetDynamicNode(1046); //test root nodes - Assert.IsTrue(doc.IsFirst()); - doc = GetDynamicNode(1172); - Assert.IsFalse(doc.IsFirst()); - doc = GetDynamicNode(1173); //test normal nodes - Assert.IsTrue(doc.IsFirst()); - doc = GetDynamicNode(1175); - Assert.IsFalse(doc.IsFirst()); - } - - [Ignore] - [Test] - public void Is_Not_First() - { - var doc = GetDynamicNode(1046); //test root nodes - Assert.IsFalse(doc.IsNotFirst()); - doc = GetDynamicNode(1172); - Assert.IsTrue(doc.IsNotFirst()); - doc = GetDynamicNode(1173); //test normal nodes - Assert.IsFalse(doc.IsNotFirst()); - doc = GetDynamicNode(1175); - Assert.IsTrue(doc.IsNotFirst()); - } - - [Ignore] - [Test] - public void Is_Position() - { - var doc = GetDynamicNode(1046); //test root nodes - Assert.IsTrue(doc.IsPosition(0)); - doc = GetDynamicNode(1172); - Assert.IsTrue(doc.IsPosition(1)); - doc = GetDynamicNode(1173); //test normal nodes - Assert.IsTrue(doc.IsPosition(0)); - doc = GetDynamicNode(1175); - Assert.IsTrue(doc.IsPosition(1)); - } - - [Test] - public void Children_GroupBy_DocumentTypeAlias() - { - var doc = GetDynamicNode(1046); - - var found1 = doc.Children.GroupBy("DocumentTypeAlias"); - - var casted = (IEnumerable>)(found1); - Assert.AreEqual(2, casted.Count()); - Assert.AreEqual(2, casted.Single(x => x.Key.ToString() == "Home").Count()); - Assert.AreEqual(1, casted.Single(x => x.Key.ToString() == "CustomDocument").Count()); - } - - [Test] - public void Children_Where_DocumentTypeAlias() - { - var doc = GetDynamicNode(1046); - - var found1 = doc.Children.Where("DocumentTypeAlias == \"CustomDocument\""); - var found2 = doc.Children.Where("DocumentTypeAlias == \"Home\""); - - Assert.AreEqual(1, found1.Count()); - Assert.AreEqual(2, found2.Count()); - } - - [Test] - public void Children_Where_NodeTypeAlias() - { - var doc = GetDynamicNode(1046); - - var found1 = doc.Children.Where("NodeTypeAlias == \"CustomDocument\""); - var found2 = doc.Children.Where("NodeTypeAlias == \"Home\""); - - Assert.AreEqual(1, found1.Count()); - Assert.AreEqual(2, found2.Count()); - } - - [Test] - public void Children_Order_By_Update_Date() - { - var asDynamic = GetDynamicNode(1173); - - var ordered = asDynamic.Children.OrderBy("UpdateDate"); - var casted = (IEnumerable)ordered; - - var correctOrder = new[] { 1178, 1177, 1174, 1176 }; - for (var i = 0; i < correctOrder.Length ;i++) - { - Assert.AreEqual(correctOrder[i], ((dynamic)casted.ElementAt(i)).Id); - } - - } - - [Test] - public void Children_Order_By_Update_Date_Descending() - { - var asDynamic = GetDynamicNode(1173); - - var ordered = asDynamic.Children.OrderBy("UpdateDate desc"); - var casted = (IEnumerable)ordered; - - var correctOrder = new[] { 1176, 1174, 1177, 1178 }; - for (var i = 0; i < correctOrder.Length; i++) - { - Assert.AreEqual(correctOrder[i], ((dynamic)casted.ElementAt(i)).Id); - } - - } - - [Test] - public void HasProperty() - { - var asDynamic = GetDynamicNode(1173); - - var hasProp = asDynamic.HasProperty("umbracoUrlAlias"); - - Assert.AreEqual(true, (bool)hasProp); - - } - - [Test] - public void Skip() - { - var asDynamic = GetDynamicNode(1173); - - var skip = asDynamic.Children.Skip(2); - var casted = (IEnumerable)skip; - - Assert.AreEqual(2, casted.Count()); - Assert.IsTrue(casted.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[]{1177, 1178})); - - } - - [Test] - public void HasValue() - { - var asDynamic = GetDynamicNode(1173); - - var hasValue = asDynamic.HasValue("umbracoUrlAlias"); - var noValue = asDynamic.HasValue("blahblahblah"); - - Assert.IsTrue(hasValue); - Assert.IsFalse(noValue); - } - - [Test] - public void Take() - { - var asDynamic = GetDynamicNode(1173); - - var take = asDynamic.Children.Take(2); - var casted = (IEnumerable)take; - - Assert.AreEqual(2, casted.Count()); - Assert.IsTrue(casted.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1174, 1176 })); - } - - [Test] - public void Ancestors_Where_Visible() - { - var asDynamic = GetDynamicNode(1174); - - var whereVisible = asDynamic.Ancestors().Where("Visible"); - var casted = (IEnumerable)whereVisible; - - Assert.AreEqual(1, casted.Count()); - - } - - [Test] - public void Visible() - { - var asDynamicHidden = GetDynamicNode(1046); - var asDynamicVisible = GetDynamicNode(1173); - - Assert.IsFalse(asDynamicHidden.Visible); - Assert.IsTrue(asDynamicVisible.Visible); - } - - [Test] - public void Ensure_TinyMCE_Converted_Type_User_Property() - { - var asDynamic = GetDynamicNode(1173); - - Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(asDynamic.Content.GetType())); - Assert.AreEqual("
This is some content
", asDynamic.Content.ToString()); - } - - [Ignore] - [Test] - public void Get_Children_With_Pluralized_Alias() - { - var asDynamic = GetDynamicNode(1173); - - Action doAssert = d => - { - Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(d)); - var casted = (IEnumerable)d; - Assert.AreEqual(2, casted.Count()); - }; + var result = doc.Children() + .Where("selectedNodes.Split(splitTerm, splitOptions).Length == 3", paramVals) + .FirstOrDefault(); + + Assert.IsNotNull(result); + Assert.AreEqual(4444, result.Id); + } + + [Ignore("We are ignoring this test because currently our ExpressionParser class cannot deal with this... it needs some serious TLC but it is very complex.")] + [Test] + public void Complex_Linq() + { + var doc = GetDynamicNode(1173); + + var paramVals = new Dictionary { { "splitTerm", new char[] { ',' } }, { "searchId", "1173" } }; + var result = doc.Ancestors().OrderBy("level") + .Single() + .Descendants() + .Where("selectedNodes != null && selectedNodes != String.Empty && selectedNodes.Split(splitTerm).Contains(searchId)", paramVals) + .FirstOrDefault(); + + Assert.IsNotNull(result); + Assert.AreEqual(4444, result.Id); + } + + [Test] + public void Index() + { + var doc = GetDynamicNode(1173); + Assert.AreEqual(0, doc.Index()); + doc = GetDynamicNode(1176); + Assert.AreEqual(1, doc.Index()); + doc = GetDynamicNode(1177); + Assert.AreEqual(2, doc.Index()); + doc = GetDynamicNode(1178); + Assert.AreEqual(3, doc.Index()); + } + + [Test] + public virtual void Is_First_Root_Nodes() + { + var doc = GetDynamicNode(1046); //test root nodes + Assert.IsTrue(doc.IsFirst()); + doc = GetDynamicNode(1172); + Assert.IsFalse(doc.IsFirst()); + } + + [Test] + public void Is_First() + { + var doc = GetDynamicNode(1173); //test normal nodes + Assert.IsTrue(doc.IsFirst()); + doc = GetDynamicNode(1175); + Assert.IsFalse(doc.IsFirst()); + } + + [Test] + public virtual void Is_Not_First_Root_Nodes() + { + var doc = GetDynamicNode(1046); //test root nodes + Assert.IsFalse(doc.IsNotFirst()); + doc = GetDynamicNode(1172); + Assert.IsTrue(doc.IsNotFirst()); + } + + [Test] + public void Is_Not_First() + { + var doc = GetDynamicNode(1173); //test normal nodes + Assert.IsFalse(doc.IsNotFirst()); + doc = GetDynamicNode(1175); + Assert.IsTrue(doc.IsNotFirst()); + } + + [Test] + public virtual void Is_Position_Root_Nodes() + { + var doc = GetDynamicNode(1046); //test root nodes + Assert.IsTrue(doc.IsPosition(0)); + doc = GetDynamicNode(1172); + Assert.IsTrue(doc.IsPosition(1)); + } + + [Test] + public void Is_Position() + { + var doc = GetDynamicNode(1173); //test normal nodes + Assert.IsTrue(doc.IsPosition(0)); + doc = GetDynamicNode(1175); + Assert.IsTrue(doc.IsPosition(1)); + } + + [Test] + public void Children_GroupBy_DocumentTypeAlias() + { + var doc = GetDynamicNode(1046); + + var found1 = doc.Children.GroupBy("DocumentTypeAlias"); + + var casted = (IEnumerable>)(found1); + Assert.AreEqual(2, casted.Count()); + Assert.AreEqual(2, casted.Single(x => x.Key.ToString() == "Home").Count()); + Assert.AreEqual(1, casted.Single(x => x.Key.ToString() == "CustomDocument").Count()); + } + + [Test] + public void Children_Where_DocumentTypeAlias() + { + var doc = GetDynamicNode(1046); + + var found1 = doc.Children.Where("DocumentTypeAlias == \"CustomDocument\""); + var found2 = doc.Children.Where("DocumentTypeAlias == \"Home\""); + + Assert.AreEqual(1, found1.Count()); + Assert.AreEqual(2, found2.Count()); + } + + [Test] + public void Children_Where_NodeTypeAlias() + { + var doc = GetDynamicNode(1046); + + var found1 = doc.Children.Where("NodeTypeAlias == \"CustomDocument\""); + var found2 = doc.Children.Where("NodeTypeAlias == \"Home\""); + + Assert.AreEqual(1, found1.Count()); + Assert.AreEqual(2, found2.Count()); + } + + [Test] + public void Children_Order_By_Update_Date() + { + var asDynamic = GetDynamicNode(1173); + + var ordered = asDynamic.Children.OrderBy("UpdateDate"); + var casted = (IEnumerable)ordered; + + var correctOrder = new[] { 1178, 1177, 1174, 1176 }; + for (var i = 0; i < correctOrder.Length; i++) + { + Assert.AreEqual(correctOrder[i], ((dynamic)casted.ElementAt(i)).Id); + } + + } + + [Test] + public void Children_Order_By_Update_Date_Descending() + { + var asDynamic = GetDynamicNode(1173); + + var ordered = asDynamic.Children.OrderBy("UpdateDate desc"); + var casted = (IEnumerable)ordered; + + var correctOrder = new[] { 1176, 1174, 1177, 1178 }; + for (var i = 0; i < correctOrder.Length; i++) + { + Assert.AreEqual(correctOrder[i], ((dynamic)casted.ElementAt(i)).Id); + } + + } + + [Test] + public void HasProperty() + { + var asDynamic = GetDynamicNode(1173); + + var hasProp = asDynamic.HasProperty("umbracoUrlAlias"); + + Assert.AreEqual(true, (bool)hasProp); + + } + + [Test] + public void Skip() + { + var asDynamic = GetDynamicNode(1173); + + var skip = asDynamic.Children.Skip(2); + var casted = (IEnumerable)skip; + + Assert.AreEqual(2, casted.Count()); + Assert.IsTrue(casted.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1177, 1178 })); - doAssert(asDynamic.Homes); //pluralized alias - doAssert(asDynamic.homes); //pluralized alias - doAssert(asDynamic.CustomDocuments); //pluralized alias - doAssert(asDynamic.customDocuments); //pluralized alias - } + } + + [Test] + public void HasValue() + { + var asDynamic = GetDynamicNode(1173); - [Test] - public void GetPropertyValue_Non_Reflected() - { - var asDynamic = GetDynamicNode(1174); - - Assert.AreEqual("Custom data with same property name as the member name", asDynamic.GetPropertyValue("creatorName")); - Assert.AreEqual("Custom data with same property name as the member name", asDynamic.GetPropertyValue("CreatorName")); - } + var hasValue = asDynamic.HasValue("umbracoUrlAlias"); + var noValue = asDynamic.HasValue("blahblahblah"); - [Ignore] - [Test] - public void GetPropertyValue_Reflected() - { - var asDynamic = GetDynamicNode(1174); - - Assert.AreEqual("admin", asDynamic.GetPropertyValue("@creatorName")); - Assert.AreEqual("admin", asDynamic.GetPropertyValue("@CreatorName")); - } - - [Test] - public void Get_User_Property_With_Same_Name_As_Member_Property() - { - var asDynamic = GetDynamicNode(1174); + Assert.IsTrue(hasValue); + Assert.IsFalse(noValue); + } - Assert.AreEqual("Custom data with same property name as the member name", asDynamic.creatorName); - - //because CreatorName is defined on DynamicNode, it will not return the user defined property - Assert.AreEqual("admin", asDynamic.CreatorName); - } - - [Ignore] - [Test] - public void Get_Member_Property() - { - var asDynamic = GetDynamicNode(1173); - - Assert.AreEqual((int) 2, (int) asDynamic.Level); - Assert.AreEqual((int) 2, (int) asDynamic.level); - - Assert.AreEqual((int) 1046, (int) asDynamic.ParentId); - Assert.AreEqual((int) 1046, (int) asDynamic.parentId); - } + [Test] + public void Take() + { + var asDynamic = GetDynamicNode(1173); - [Test] - public void Get_Children() - { - var asDynamic = GetDynamicNode(1173); + var take = asDynamic.Children.Take(2); + var casted = (IEnumerable)take; - var children = asDynamic.Children; - Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(children)); + Assert.AreEqual(2, casted.Count()); + Assert.IsTrue(casted.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1174, 1176 })); + } - var childrenAsList = asDynamic.ChildrenAsList; //test ChildrenAsList too - Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(childrenAsList)); + [Test] + public void Ancestors_Where_Visible() + { + var asDynamic = GetDynamicNode(1174); - var castChildren = (IEnumerable)children; - Assert.AreEqual(4, castChildren.Count()); + var whereVisible = asDynamic.Ancestors().Where("Visible"); + var casted = (IEnumerable)whereVisible; - var castChildrenAsList = (IEnumerable)childrenAsList; - Assert.AreEqual(4, castChildrenAsList.Count()); - } + Assert.AreEqual(1, casted.Count()); - [Test] - public void Ancestor_Or_Self() - { - var asDynamic = GetDynamicNode(1173); + } - var result = asDynamic.AncestorOrSelf(); + [Test] + public void Visible() + { + var asDynamicHidden = GetDynamicNode(1046); + var asDynamicVisible = GetDynamicNode(1173); - Assert.IsNotNull(result); + Assert.IsFalse(asDynamicHidden.Visible); + Assert.IsTrue(asDynamicVisible.Visible); + } - Assert.AreEqual((int) 1046, (int) result.Id); - } + [Test] + public void Ensure_TinyMCE_Converted_Type_User_Property() + { + var asDynamic = GetDynamicNode(1173); - [Test] - public void Ancestors_Or_Self() - { - var asDynamic = GetDynamicNode(1174); + Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(asDynamic.Content.GetType())); + Assert.AreEqual("
This is some content
", asDynamic.Content.ToString()); + } - var result = asDynamic.AncestorsOrSelf(); + [Test] + public void Get_Children_With_Pluralized_Alias() + { + var asDynamic = GetDynamicNode(1173); - Assert.IsNotNull(result); + Action doAssert = d => + { + Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(d)); + var casted = (IEnumerable)d; + Assert.AreEqual(2, casted.Count()); + }; - var list = (IEnumerable)result; - Assert.AreEqual(3, list.Count()); - Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1174, 1173, 1046 })); - } + doAssert(asDynamic.Homes); //pluralized alias + doAssert(asDynamic.homes); //pluralized alias + doAssert(asDynamic.CustomDocuments); //pluralized alias + doAssert(asDynamic.customDocuments); //pluralized alias + } - [Test] - public void Ancestors() - { - var asDynamic = GetDynamicNode(1174); + [Test] + public void GetPropertyValue_Non_Reflected() + { + var asDynamic = GetDynamicNode(1174); - var result = asDynamic.Ancestors(); + Assert.AreEqual("Custom data with same property name as the member name", asDynamic.GetPropertyValue("creatorName")); + Assert.AreEqual("Custom data with same property name as the member name", asDynamic.GetPropertyValue("CreatorName")); + } - Assert.IsNotNull(result); + [Test] + public void GetPropertyValue_Reflected() + { + var asDynamic = GetDynamicNode(1174); - var list = (IEnumerable)result; - Assert.AreEqual(2, list.Count()); - Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1173, 1046 })); - } + Assert.AreEqual("admin", asDynamic.GetPropertyValue("@creatorName")); + Assert.AreEqual("admin", asDynamic.GetPropertyValue("@CreatorName")); + } - [Test] - public void Descendants_Or_Self() - { - var asDynamic = GetDynamicNode(1046); + [Test] + public void Get_User_Property_With_Same_Name_As_Member_Property() + { + var asDynamic = GetDynamicNode(1174); - var result = asDynamic.DescendantsOrSelf(); + Assert.AreEqual("Custom data with same property name as the member name", asDynamic.creatorName); - Assert.IsNotNull(result); + //because CreatorName is defined on DynamicNode, it will not return the user defined property + Assert.AreEqual("admin", asDynamic.CreatorName); + } - var list = (IEnumerable)result; - Assert.AreEqual(9, list.Count()); - Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1046, 1173, 1174, 1176, 1175, 4444 })); - } + [Test] + public void Get_Member_Property() + { + var asDynamic = GetDynamicNode(1173); - [Test] - public void Descendants() - { - var asDynamic = GetDynamicNode(1046); + Assert.AreEqual((int)2, (int)asDynamic.Level); + Assert.AreEqual((int)2, (int)asDynamic.level); - var result = asDynamic.Descendants(); + Assert.AreEqual((int)1046, (int)asDynamic.ParentId); + Assert.AreEqual((int)1046, (int)asDynamic.parentId); + } - Assert.IsNotNull(result); + [Test] + public void Get_Children() + { + var asDynamic = GetDynamicNode(1173); - var list = (IEnumerable)result; - Assert.AreEqual(8, list.Count()); - Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1173, 1174, 1176, 1175, 4444 })); - } + var children = asDynamic.Children; + Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(children)); - [Test] - public void Up() - { - var asDynamic = GetDynamicNode(1173); + var childrenAsList = asDynamic.ChildrenAsList; //test ChildrenAsList too + Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(childrenAsList)); - var result = asDynamic.Up(); + var castChildren = (IEnumerable)children; + Assert.AreEqual(4, castChildren.Count()); - Assert.IsNotNull(result); + var castChildrenAsList = (IEnumerable)childrenAsList; + Assert.AreEqual(4, castChildrenAsList.Count()); + } - Assert.AreEqual((int) 1046, (int) result.Id); - } + [Test] + public void Ancestor_Or_Self() + { + var asDynamic = GetDynamicNode(1173); - [Test] - public void Down() - { - var asDynamic = GetDynamicNode(1173); + var result = asDynamic.AncestorOrSelf(); - var result = asDynamic.Down(); + Assert.IsNotNull(result); - Assert.IsNotNull(result); + Assert.AreEqual((int)1046, (int)result.Id); + } - Assert.AreEqual((int) 1174, (int) result.Id); - } + [Test] + public void Ancestors_Or_Self() + { + var asDynamic = GetDynamicNode(1174); - [Test] - public void Next() - { - var asDynamic = GetDynamicNode(1173); + var result = asDynamic.AncestorsOrSelf(); - var result = asDynamic.Next(); + Assert.IsNotNull(result); - Assert.IsNotNull(result); + var list = (IEnumerable)result; + Assert.AreEqual(3, list.Count()); + Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1174, 1173, 1046 })); + } - Assert.AreEqual((int) 1175, (int) result.Id); - } + [Test] + public void Ancestors() + { + var asDynamic = GetDynamicNode(1174); - [Test] - public void Next_Without_Sibling() - { - var asDynamic = GetDynamicNode(1178); + var result = asDynamic.Ancestors(); - Assert.IsNull(asDynamic.Next()); - } + Assert.IsNotNull(result); - [Test] - public void Previous_Without_Sibling() - { - var asDynamic = GetDynamicNode(1173); + var list = (IEnumerable)result; + Assert.AreEqual(2, list.Count()); + Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1173, 1046 })); + } - Assert.IsNull(asDynamic.Previous()); - } + [Test] + public void Descendants_Or_Self() + { + var asDynamic = GetDynamicNode(1046); - [Test] - public void Previous() - { - var asDynamic = GetDynamicNode(1176); + var result = asDynamic.DescendantsOrSelf(); - var result = asDynamic.Previous(); + Assert.IsNotNull(result); - Assert.IsNotNull(result); + var list = (IEnumerable)result; + Assert.AreEqual(9, list.Count()); + Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1046, 1173, 1174, 1176, 1175, 4444 })); + } - Assert.AreEqual((int) 1174, (int) result.Id); - } - } + [Test] + public void Descendants() + { + var asDynamic = GetDynamicNode(1046); - /// - /// Extension methods used in tests - /// - public static class TestExtensionMethods - { - public static bool ContainsValue(this string s, int val) - { - return s.Contains(val.ToString()); - } - } + var result = asDynamic.Descendants(); + + Assert.IsNotNull(result); + + var list = (IEnumerable)result; + Assert.AreEqual(8, list.Count()); + Assert.IsTrue(list.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1173, 1174, 1176, 1175, 4444 })); + } + + [Test] + public void Up() + { + var asDynamic = GetDynamicNode(1173); + + var result = asDynamic.Up(); + + Assert.IsNotNull(result); + + Assert.AreEqual((int)1046, (int)result.Id); + } + + [Test] + public void Down() + { + var asDynamic = GetDynamicNode(1173); + + var result = asDynamic.Down(); + + Assert.IsNotNull(result); + + Assert.AreEqual((int)1174, (int)result.Id); + } + + [Test] + public void Next() + { + var asDynamic = GetDynamicNode(1173); + + var result = asDynamic.Next(); + + Assert.IsNotNull(result); + + Assert.AreEqual((int)1175, (int)result.Id); + } + + [Test] + public void Next_Without_Sibling() + { + var asDynamic = GetDynamicNode(1178); + + Assert.IsNull(asDynamic.Next()); + } + + [Test] + public void Previous_Without_Sibling() + { + var asDynamic = GetDynamicNode(1173); + + Assert.IsNull(asDynamic.Previous()); + } + + [Test] + public void Previous() + { + var asDynamic = GetDynamicNode(1176); + + var result = asDynamic.Previous(); + + Assert.IsNotNull(result); + + Assert.AreEqual((int)1174, (int)result.Id); + } + } + + /// + /// Extension methods used in tests + /// + public static class TestExtensionMethods + { + public static bool ContainsValue(this string s, int val) + { + return s.Contains(val.ToString()); + } + } } \ No newline at end of file diff --git a/src/Umbraco.Tests/PublishedContent/DynamicNodeTests.cs b/src/Umbraco.Tests/PublishedContent/DynamicNodeTests.cs index bd8944a027..0d85955136 100644 --- a/src/Umbraco.Tests/PublishedContent/DynamicNodeTests.cs +++ b/src/Umbraco.Tests/PublishedContent/DynamicNodeTests.cs @@ -54,6 +54,27 @@ namespace Umbraco.Tests.PublishedContent } + [Test] + [Ignore("This test will never work unless DynamicNode is refactored a lot in order to get a list of root nodes since root nodes don't have a parent to look up")] + public override void Is_First_Root_Nodes() + { + base.Is_First_Root_Nodes(); + } + + [Test] + [Ignore("This test will never work unless DynamicNode is refactored a lot in order to get a list of root nodes since root nodes don't have a parent to look up")] + public override void Is_Not_First_Root_Nodes() + { + base.Is_Not_First_Root_Nodes(); + } + + [Test] + [Ignore("This test will never work unless DynamicNode is refactored a lot in order to get a list of root nodes since root nodes don't have a parent to look up")] + public override void Is_Position_Root_Nodes() + { + base.Is_Position_Root_Nodes(); + } + public override void TearDown() { base.TearDown(); diff --git a/src/Umbraco.Tests/PublishedContent/DynamicPublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/DynamicPublishedContentTests.cs index e8bb815802..40049d8d2f 100644 --- a/src/Umbraco.Tests/PublishedContent/DynamicPublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/DynamicPublishedContentTests.cs @@ -1,7 +1,9 @@ using System; +using System.IO; using System.Linq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Configuration; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Web; @@ -24,6 +26,8 @@ namespace Umbraco.Tests.PublishedContent typeof(YesNoPropertyEditorValueConverter) }); + UmbracoSettings.SettingsFilePath = Core.IO.IOHelper.MapPath(Core.IO.SystemDirectories.Config + Path.DirectorySeparatorChar, false); + //need to specify a custom callback for unit tests PublishedContentHelper.GetDataTypeCallback = (docTypeAlias, propertyAlias) => { diff --git a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs index 3c92cfa223..80bef30574 100644 --- a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs +++ b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Dynamic; using System.Linq; @@ -30,11 +31,11 @@ namespace umbraco.MacroEngines { public class DynamicNode : DynamicObject, INode { - /// - /// This callback is used only so we can set it dynamically for use in unit tests - /// - internal static Func GetDataTypeCallback = (docTypeAlias, propertyAlias) => - ContentType.GetDataType(docTypeAlias, propertyAlias); + /// + /// This callback is used only so we can set it dynamically for use in unit tests + /// + internal static Func GetDataTypeCallback = (docTypeAlias, propertyAlias) => + ContentType.GetDataType(docTypeAlias, propertyAlias); #region consts // these are private readonlys as const can't be Guids @@ -45,6 +46,9 @@ namespace umbraco.MacroEngines //private readonly Guid DATATYPE_INTEGER_GUID = new Guid("1413afcb-d19a-4173-8e9a-68288d2a73b8"); #endregion + private DynamicNodeList _cachedChildren; + private readonly ConcurrentDictionary _cachedMemberOutput = new ConcurrentDictionary(); + internal readonly DynamicBackingItem n; public DynamicNodeList ownerList; @@ -154,13 +158,20 @@ namespace umbraco.MacroEngines { get { - List children = n.ChildrenAsList; - //testing - if (children.Count == 0 && n.Id == 0) + if (_cachedChildren == null) { - return new DynamicNodeList(new List { this.n }); + List children = n.ChildrenAsList; + //testing + if (children.Count == 0 && n.Id == 0) + { + _cachedChildren = new DynamicNodeList(new List { this.n }); + } + else + { + _cachedChildren = new DynamicNodeList(n.ChildrenAsList); + } } - return new DynamicNodeList(n.ChildrenAsList); + return _cachedChildren; } } public DynamicNodeList XPath(string xPath) @@ -234,12 +245,12 @@ namespace umbraco.MacroEngines throw new NullReferenceException("DynamicNode wasn't initialized with an underlying NodeFactory.Node"); } } - - + + public DynamicNodeList Search(string term, bool useWildCards = true, string searchProvider = null) { var searcher = Examine.ExamineManager.Instance.DefaultSearchProvider; - if(!string.IsNullOrEmpty(searchProvider)) + if (!string.IsNullOrEmpty(searchProvider)) searcher = Examine.ExamineManager.Instance.SearchProviderCollection[searchProvider]; var t = term.Escape().Value; @@ -279,13 +290,13 @@ namespace umbraco.MacroEngines var s = Examine.ExamineManager.Instance.DefaultSearchProvider; if (searchProvider != null) s = searchProvider; - + var results = s.Search(criteria); return ExamineSearchUtill.ConvertSearchResultToDynamicNode(results); } - + public bool HasProperty(string name) { @@ -406,125 +417,99 @@ namespace umbraco.MacroEngines } return result; } - private List GetAncestorOrSelfNodeTypeAlias(DynamicBackingItem node) - { - List list = new List(); - if (node != null) - { - if (node.Type == DynamicBackingItemType.Content) - { - //find the doctype node, so we can walk it's parent's tree- not the working.parent content tree - CMSNode working = ContentType.GetByAlias(node.NodeTypeAlias); - while (working != null) - { - //NOTE: I'm not sure if anyone has ever tested this but if you get working.Parent it will return a CMSNode and - // it will never be castable to a 'ContentType' object - // pretty sure the only reason why this method works for the one place that it is used is that it returns - // the current node's alias which is all that is actually requried, this is just added overhead for no - // reason - if ((working as ContentType) != null) - { - list.Add((working as ContentType).Alias); - } + private static Dictionary, Type> _razorDataTypeModelTypes = null; + private static readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(); + + internal static Dictionary, Type> RazorDataTypeModelTypes + { + get + { + using (var l = new UpgradeableReadLock(_locker)) + { + if (_razorDataTypeModelTypes == null) + { + l.UpgradeToWriteLock(); + + var foundTypes = new Dictionary, Type>(); + try { - working = working.Parent; + PluginManager.Current.ResolveRazorDataTypeModels() + .ToList() + .ConvertAll(type => + { + var razorDataTypeModelAttributes = type.GetCustomAttributes(true); + return razorDataTypeModelAttributes.ToList().ConvertAll(razorDataTypeModelAttribute => + { + var g = razorDataTypeModelAttribute.DataTypeEditorId; + var priority = razorDataTypeModelAttribute.Priority; + return new KeyValuePair, Type>(new System.Tuple(g, priority), type); + }); + }) + .SelectMany(item => item) + .ToList() + .ForEach(item => + { + System.Tuple key = item.Key; + if (!foundTypes.ContainsKey(key)) + { + foundTypes.Add(key, item.Value); + } + }); + + //there is no error, so set the collection + _razorDataTypeModelTypes = foundTypes; + } - catch (ArgumentException) + catch (Exception ex) { - break; + LogHelper.Warn("Exception occurred while populating cache, will keep RazorDataTypeModelTypes to null so that this error remains visible and you don't end up with an empty cache with silent failure." + + string.Format("The exception was {0} and the message was {1}. {2}", ex.GetType().FullName, ex.Message, ex.StackTrace)); } + } - } - else - { - return null; + return _razorDataTypeModelTypes; } } - return list; } - private static Dictionary, Type> _razorDataTypeModelTypes = null; - private static readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(); - - internal static Dictionary, Type> RazorDataTypeModelTypes - { - get - { - using (var l = new UpgradeableReadLock(_locker)) - { - if (_razorDataTypeModelTypes == null) - { - l.UpgradeToWriteLock(); - - var foundTypes = new Dictionary, Type>(); - - try - { - PluginManager.Current.ResolveRazorDataTypeModels() - .ToList() - .ConvertAll(type => - { - var razorDataTypeModelAttributes = type.GetCustomAttributes(true); - return razorDataTypeModelAttributes.ToList().ConvertAll(razorDataTypeModelAttribute => - { - var g = razorDataTypeModelAttribute.DataTypeEditorId; - var priority = razorDataTypeModelAttribute.Priority; - return new KeyValuePair, Type>(new System.Tuple(g, priority), type); - }); - }) - .SelectMany(item => item) - .ToList() - .ForEach(item => - { - System.Tuple key = item.Key; - if (!foundTypes.ContainsKey(key)) - { - foundTypes.Add(key, item.Value); - } - }); - - //NOTE: We really dont need to log this? - //var i = 1; - //foreach (var item in foundTypes) - //{ - // HttpContext.Current.Trace.Write(string.Format("{0}/{1}: {2}@{4} => {3}", i, foundTypes.Count, item.Key.Item1, item.Value.FullName, item.Key.Item2)); - // i++; - //} - - //there is no error, so set the collection - _razorDataTypeModelTypes = foundTypes; - - } - catch (Exception ex) - { - LogHelper.Warn("Exception occurred while populating cache, will keep RazorDataTypeModelTypes to null so that this error remains visible and you don't end up with an empty cache with silent failure." - + string.Format("The exception was {0} and the message was {1}. {2}", ex.GetType().FullName, ex.Message, ex.StackTrace)); - } - - } - return _razorDataTypeModelTypes; - } - } - } - - private static Guid GetDataType(string docTypeAlias, string propertyAlias) - { - return GetDataTypeCallback(docTypeAlias, propertyAlias); - } + private static Guid GetDataType(string docTypeAlias, string propertyAlias) + { + return GetDataTypeCallback(docTypeAlias, propertyAlias); + } public override bool TryGetMember(GetMemberBinder binder, out object result) { - var name = binder.Name; - result = null; //this will never be returned - if (name == "ChildrenAsList" || name == "Children") + //check the cache first! + if (_cachedMemberOutput.TryGetValue(name, out result)) { - result = GetChildrenAsList; return true; } + + result = null; //this will never be returned + + if (name.InvariantEquals("ChildrenAsList") || name.InvariantEquals("Children")) + { + result = GetChildrenAsList; + //cache the result so we don't have to re-process the whole thing + _cachedMemberOutput.TryAdd(name, result); + return true; + } + if (binder.Name.InvariantEquals("parentId")) + { + var parent = n.Parent; + if (parent == null) + { + throw new InvalidOperationException(string.Format("The node {0} does not have a parent", Id)); + } + result = parent.Id; + _cachedMemberOutput.TryAdd(name, result); + return true; + } + bool propertyExists = false; if (n != null) { @@ -554,8 +539,8 @@ namespace umbraco.MacroEngines //contextAlias is the node which the property data was returned from //Guid dataType = ContentType.GetDataType(data.ContextAlias, data.Alias); - var dataType = GetDataType(data.ContextAlias, data.Alias); - + var dataType = GetDataType(data.ContextAlias, data.Alias); + var staticMapping = UmbracoSettings.RazorDataTypeModelStaticMapping.FirstOrDefault(mapping => { return mapping.Applies(dataType, data.ContextAlias, data.Alias); @@ -570,19 +555,21 @@ namespace umbraco.MacroEngines if (TryCreateInstanceRazorDataTypeModel(dataType, dataTypeType, data.Value, out instance)) { result = instance; + //cache the result so we don't have to re-process the whole thing + _cachedMemberOutput.TryAdd(name, result); return true; } else { - LogHelper.Warn(string.Format("Failed to create the instance of the model binder")); + LogHelper.Warn(string.Format("Failed to create the instance of the model binder")); } } else { - LogHelper.Warn(string.Format("staticMapping type name {0} came back as null from Type.GetType; check the casing, assembly presence, assembly framework version, namespace", staticMapping.TypeName)); + LogHelper.Warn(string.Format("staticMapping type name {0} came back as null from Type.GetType; check the casing, assembly presence, assembly framework version, namespace", staticMapping.TypeName)); } } - + if (RazorDataTypeModelTypes != null && RazorDataTypeModelTypes.Any(model => model.Key.Item1 == dataType) && dataType != Guid.Empty) { var razorDataTypeModelDefinition = RazorDataTypeModelTypes.Where(model => model.Key.Item1 == dataType).OrderByDescending(model => model.Key.Item2).FirstOrDefault(); @@ -593,35 +580,26 @@ namespace umbraco.MacroEngines if (TryCreateInstanceRazorDataTypeModel(dataType, dataTypeType, data.Value, out instance)) { result = instance; + //cache the result so we don't have to re-process the whole thing + _cachedMemberOutput.TryAdd(name, result); return true; } else { - LogHelper.Warn(string.Format("Failed to create the instance of the model binder")); + LogHelper.Warn(string.Format("Failed to create the instance of the model binder")); } } else { - LogHelper.Warn(string.Format("Could not get the dataTypeType for the RazorDataTypeModel")); + LogHelper.Warn(string.Format("Could not get the dataTypeType for the RazorDataTypeModel")); } } - else - { - //NOTE: Do we really want to log this? I'm not sure. - //if (RazorDataTypeModelTypes == null) - //{ - // HttpContext.Current.Trace.Write(string.Format("RazorDataTypeModelTypes is null, probably an exception while building the cache, falling back to ConvertPropertyValueByDataType", dataType)); - //} - //else - //{ - // HttpContext.Current.Trace.Write(string.Format("GUID {0} does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType", dataType)); - //} - - } //convert the string value to a known type - return ConvertPropertyValueByDataType(ref result, name, dataType); - + var returnVal = ConvertPropertyValueByDataType(ref result, name, dataType); + //cache the result so we don't have to re-process the whole thing + _cachedMemberOutput.TryAdd(name, result); + return returnVal; } //check if the alias is that of a child type @@ -629,39 +607,30 @@ namespace umbraco.MacroEngines var typeChildren = n.ChildrenAsList; if (typeChildren != null) { - var filteredTypeChildren = typeChildren.Where(x => - { - List ancestorAliases = GetAncestorOrSelfNodeTypeAlias(x); - if (ancestorAliases == null) - { - return false; - } - return ancestorAliases.Any(alias => alias == name || MakePluralName(alias) == name); - }); + + var filteredTypeChildren = typeChildren + .Where(x => x.NodeTypeAlias.InvariantEquals(name) || x.NodeTypeAlias.MakePluralName().InvariantEquals(binder.Name)) + .ToArray(); if (filteredTypeChildren.Any()) { result = new DynamicNodeList(filteredTypeChildren); + //cache the result so we don't have to re-process the whole thing + _cachedMemberOutput.TryAdd(name, result); return true; } } - try + //lookup the property using reflection + + result = GetReflectedProperty(binder.Name); + + if (result != null) { - result = n.GetType().InvokeMember(binder.Name, - System.Reflection.BindingFlags.GetProperty | - System.Reflection.BindingFlags.Instance | - System.Reflection.BindingFlags.Public, - null, - n, - null); + _cachedMemberOutput.TryAdd(name, result); return true; } - catch - { - //result = null; - //return false; - } + } //if property access, type lookup and member invoke all failed @@ -679,6 +648,42 @@ namespace umbraco.MacroEngines } return true; } + + private object GetReflectedProperty(string alias) + { + Func> getMember = + memberAlias => + { + try + { + return new Attempt(true, + n.GetType().InvokeMember(memberAlias, + System.Reflection.BindingFlags.GetProperty | + System.Reflection.BindingFlags.Instance | + System.Reflection.BindingFlags.Public, + null, + n, + null)); + } + catch (MissingMethodException ex) + { + return new Attempt(ex); + } + }; + + //try with the current casing + var attempt = getMember(alias); + if (!attempt.Success) + { + //if we cannot get with the current alias, try changing it's case + attempt = alias[0].IsUpperCase() + ? getMember(alias.ConvertCase(StringAliasCaseType.CamelCase)) + : getMember(alias.ConvertCase(StringAliasCaseType.PascalCase)); + } + + return attempt.Success ? attempt.Result : null; + } + private bool TryCreateInstanceRazorDataTypeModel(Guid dataType, Type dataTypeType, string value, out object result) { IRazorDataTypeModel razorDataTypeModel = Activator.CreateInstance(dataTypeType, false) as IRazorDataTypeModel; @@ -689,22 +694,22 @@ namespace umbraco.MacroEngines { if (instance == null) { - LogHelper.Warn("razorDataTypeModel successfully instantiated but returned null for instance"); + LogHelper.Warn("razorDataTypeModel successfully instantiated but returned null for instance"); } - result = instance; + result = instance; return true; } else { if (instance == null) { - LogHelper.Warn("razorDataTypeModel successfully instantiated but returned null for instance"); + LogHelper.Warn("razorDataTypeModel successfully instantiated but returned null for instance"); } } } else { - LogHelper.Warn(string.Format("DataTypeModel {0} failed to instantiate, perhaps it is lacking a parameterless constructor or doesn't implement IRazorDataTypeModel?", dataTypeType.FullName)); + LogHelper.Warn(string.Format("DataTypeModel {0} failed to instantiate, perhaps it is lacking a parameterless constructor or doesn't implement IRazorDataTypeModel?", dataTypeType.FullName)); } result = null; return false; @@ -1329,15 +1334,15 @@ namespace umbraco.MacroEngines { get { - return GetChildrenAsList; - //if (n == null) return null; return n.ChildrenAsList; + return GetChildrenAsList; + //if (n == null) return null; return n.ChildrenAsList; } } - public DynamicNodeList Children - { - get { return ChildrenAsList; } - } + public DynamicNodeList Children + { + get { return ChildrenAsList; } + } public IProperty GetProperty(string alias) { @@ -1368,13 +1373,25 @@ namespace umbraco.MacroEngines } public string GetPropertyValue(string alias, string fallback) { - var prop = GetProperty(alias); - if (prop != null) return prop.Value; - return fallback; + string prop; + if (alias.StartsWith("@")) + { + var p = GetReflectedProperty(alias.TrimStart('@')); + prop = p == null ? null : p.ToString(); + } + else + { + var p = GetProperty(alias); + prop = p != null ? p.Value : null; + } + return !prop.IsNullOrWhiteSpace() ? prop : fallback; } public string GetPropertyValue(string alias, bool recursive) { - return GetPropertyValue(alias, recursive, null); + var p = alias.StartsWith("@") + ? GetReflectedProperty(alias.TrimStart('@')) + : GetPropertyValue(alias, recursive, null); + return (string)p; } public string GetPropertyValue(string alias, bool recursive, string fallback) { @@ -1433,14 +1450,24 @@ namespace umbraco.MacroEngines { return this.Index(); } - public int Index() + + /// + /// Checks if the owner list is null and attempts to create it if there is a parent. + /// + /// Successful if the owners list is not null, false if the owners list could not be created and remains null + private bool EnsureOwnersList() { if (this.ownerList == null && this.Parent != null) { var list = this.Parent.ChildrenAsList.Select(n => new DynamicNode(n)); this.ownerList = new DynamicNodeList(list); } - if (this.ownerList != null) + return this.ownerList != null; + } + + public int Index() + { + if (EnsureOwnersList()) { List container = this.ownerList.Items.ToList(); int currentIndex = container.FindIndex(n => n.Id == this.Id); @@ -1448,16 +1475,11 @@ namespace umbraco.MacroEngines { return currentIndex; } - else - { - throw new IndexOutOfRangeException(string.Format("Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list", this.Id)); - } - } - else - { - throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", this.Id)); + throw new IndexOutOfRangeException(string.Format("Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list", this.Id)); } + throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", this.Id)); } + public bool IsFirst() { return IsHelper(n => n.Index() == 0); @@ -1484,7 +1506,7 @@ namespace umbraco.MacroEngines } public bool IsPosition(int index) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1492,7 +1514,7 @@ namespace umbraco.MacroEngines } public HtmlString IsPosition(int index, string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1500,7 +1522,7 @@ namespace umbraco.MacroEngines } public HtmlString IsPosition(int index, string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } @@ -1508,7 +1530,7 @@ namespace umbraco.MacroEngines } public bool IsModZero(int modulus) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1516,7 +1538,7 @@ namespace umbraco.MacroEngines } public HtmlString IsModZero(int modulus, string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1524,7 +1546,7 @@ namespace umbraco.MacroEngines } public HtmlString IsModZero(int modulus, string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } @@ -1533,7 +1555,7 @@ namespace umbraco.MacroEngines public bool IsNotModZero(int modulus) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1541,7 +1563,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotModZero(int modulus, string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1549,7 +1571,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotModZero(int modulus, string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } @@ -1557,7 +1579,7 @@ namespace umbraco.MacroEngines } public bool IsNotPosition(int index) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1565,7 +1587,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotPosition(int index, string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1573,7 +1595,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotPosition(int index, string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } @@ -1581,7 +1603,7 @@ namespace umbraco.MacroEngines } public bool IsLast() { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1590,7 +1612,7 @@ namespace umbraco.MacroEngines } public HtmlString IsLast(string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1599,7 +1621,7 @@ namespace umbraco.MacroEngines } public HtmlString IsLast(string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } @@ -1608,7 +1630,7 @@ namespace umbraco.MacroEngines } public bool IsNotLast() { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return false; } @@ -1617,7 +1639,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotLast(string valueIfTrue) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(string.Empty); } @@ -1626,7 +1648,7 @@ namespace umbraco.MacroEngines } public HtmlString IsNotLast(string valueIfTrue, string valueIfFalse) { - if (this.ownerList == null) + if (!EnsureOwnersList()) { return new HtmlString(valueIfFalse); } @@ -1779,128 +1801,128 @@ namespace umbraco.MacroEngines return false; } - #region Explicit INode implementation - INode INode.Parent - { - get { return Parent; } - } + #region Explicit INode implementation + INode INode.Parent + { + get { return Parent; } + } - int INode.Id - { - get { return Id; } - } + int INode.Id + { + get { return Id; } + } - int INode.template - { - get { return template; } - } + int INode.template + { + get { return template; } + } - int INode.SortOrder - { - get { return SortOrder; } - } + int INode.SortOrder + { + get { return SortOrder; } + } - string INode.Name - { - get { return Name; } - } + string INode.Name + { + get { return Name; } + } - string INode.Url - { - get { return Url; } - } + string INode.Url + { + get { return Url; } + } - string INode.UrlName - { - get { return UrlName; } - } + string INode.UrlName + { + get { return UrlName; } + } - string INode.NodeTypeAlias - { - get { return NodeTypeAlias; } - } + string INode.NodeTypeAlias + { + get { return NodeTypeAlias; } + } - string INode.WriterName - { - get { return WriterName; } - } + string INode.WriterName + { + get { return WriterName; } + } - string INode.CreatorName - { - get { return CreatorName; } - } + string INode.CreatorName + { + get { return CreatorName; } + } - int INode.WriterID - { - get { return WriterID; } - } + int INode.WriterID + { + get { return WriterID; } + } - int INode.CreatorID - { - get { return CreatorID; } - } + int INode.CreatorID + { + get { return CreatorID; } + } - string INode.Path - { - get { return Path; } - } + string INode.Path + { + get { return Path; } + } - DateTime INode.CreateDate - { - get { return CreateDate; } - } + DateTime INode.CreateDate + { + get { return CreateDate; } + } - DateTime INode.UpdateDate - { - get { return UpdateDate; } - } + DateTime INode.UpdateDate + { + get { return UpdateDate; } + } - Guid INode.Version - { - get { return Version; } - } + Guid INode.Version + { + get { return Version; } + } - string INode.NiceUrl - { - get { return NiceUrl; } - } + string INode.NiceUrl + { + get { return NiceUrl; } + } - int INode.Level - { - get { return Level; } - } + int INode.Level + { + get { return Level; } + } - List INode.PropertiesAsList - { - get { return PropertiesAsList; } - } + List INode.PropertiesAsList + { + get { return PropertiesAsList; } + } - List INode.ChildrenAsList - { - get { return new List(ChildrenAsList.Select(x => x).ToList()); } - } + List INode.ChildrenAsList + { + get { return new List(ChildrenAsList.Select(x => x).ToList()); } + } - IProperty INode.GetProperty(string Alias) - { - return GetProperty(Alias); - } + IProperty INode.GetProperty(string Alias) + { + return GetProperty(Alias); + } - IProperty INode.GetProperty(string Alias, out bool propertyExists) - { - var p = GetProperty(Alias, false); - propertyExists = p != null; - return p; - } + IProperty INode.GetProperty(string Alias, out bool propertyExists) + { + var p = GetProperty(Alias, false); + propertyExists = p != null; + return p; + } - System.Data.DataTable INode.ChildrenAsTable() - { - return ChildrenAsTable(); - } + System.Data.DataTable INode.ChildrenAsTable() + { + return ChildrenAsTable(); + } - System.Data.DataTable INode.ChildrenAsTable(string nodeTypeAliasFilter) - { - return ChildrenAsTable(nodeTypeAliasFilter); - } - #endregion - } + System.Data.DataTable INode.ChildrenAsTable(string nodeTypeAliasFilter) + { + return ChildrenAsTable(nodeTypeAliasFilter); + } + #endregion + } } From 6734420c6f8f96d3a1d6e402843e6982b5eaa99c Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Thu, 21 Feb 2013 06:03:56 +0600 Subject: [PATCH 18/18] merge issue, had 2 declarations in the proj for SettingsForTests --- src/Umbraco.Tests/Umbraco.Tests.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index dc3f453ab7..497befe86d 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -287,7 +287,6 @@ -