diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs index 9c3bd8bdc7..beab6537b3 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs @@ -25,6 +25,18 @@ namespace Umbraco.Core.Configuration /// internal class UmbracoSettings { + /// + /// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config) + /// + internal static void ResetSetters() + { + _addTrailingSlash = null; + _forceSafeAliases = null; + _useLegacySchema = null; + _useDomainPrefixes = null; + _umbracoLibraryCacheDuration = null; + } + internal const string TempFriendlyXmlChildContainerNodename = ""; // "children"; /// @@ -601,6 +613,8 @@ namespace Umbraco.Core.Configuration } } + private static bool? _forceSafeAliases; + /// /// Whether to force safe aliases (no spaces, no special characters) at businesslogic level on contenttypes and propertytypes /// @@ -608,6 +622,9 @@ namespace Umbraco.Core.Configuration { get { + if (_forceSafeAliases.HasValue) + return _forceSafeAliases.Value; + string forceSafeAlias = GetKey("/settings/content/ForceSafeAliases"); if (String.IsNullOrEmpty(forceSafeAlias)) return true; @@ -622,7 +639,11 @@ namespace Umbraco.Core.Configuration return true; } } - + } + internal set + { + //used for unit testing + _forceSafeAliases = value; } } @@ -645,6 +666,8 @@ namespace Umbraco.Core.Configuration get { return GetKey("/settings/content/scripteditor/scriptFileTypes"); } } + private static int? _umbracoLibraryCacheDuration; + /// /// Gets the duration in seconds to cache queries to umbraco library member and media methods /// Default is 1800 seconds (30 minutes) @@ -653,6 +676,9 @@ namespace Umbraco.Core.Configuration { get { + if (_umbracoLibraryCacheDuration.HasValue) + return _umbracoLibraryCacheDuration.Value; + string libraryCacheDuration = GetKey("/settings/content/UmbracoLibraryCacheDuration"); if (String.IsNullOrEmpty(libraryCacheDuration)) return 1800; @@ -669,6 +695,7 @@ namespace Umbraco.Core.Configuration } } + internal set { _umbracoLibraryCacheDuration = value; } } /// diff --git a/src/Umbraco.Tests/ContentStores/PublishMediaStoreTests.cs b/src/Umbraco.Tests/ContentStores/PublishMediaStoreTests.cs index b9cc5c485d..214931138c 100644 --- a/src/Umbraco.Tests/ContentStores/PublishMediaStoreTests.cs +++ b/src/Umbraco.Tests/ContentStores/PublishMediaStoreTests.cs @@ -6,13 +6,51 @@ using Examine; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models; +using Umbraco.Tests.PublishedContent; +using Umbraco.Tests.TestHelpers; using Umbraco.Web; +using umbraco.BusinessLogic; -namespace Umbraco.Tests +namespace Umbraco.Tests.ContentStores { [TestFixture] - public class PublishMediaStoreTests + public class PublishMediaStoreTests : BaseWebTest { + public override void Initialize() + { + base.Initialize(); + //we're going to use the same initialization as the PublishedMediaTests + PublishedMediaTests.DoInitialization(GetUmbracoContext("/test", 1234)); + } + + public override void TearDown() + { + base.TearDown(); + PublishedMediaTests.DoTearDown(); + } + + [Test] + public void Get_Item_Without_Examine() + { + var user = new User(0); + var mType = global::umbraco.cms.businesslogic.media.MediaType.MakeNew(user, "TestMediaType"); + var mRoot = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot", mType, user, -1); + var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot.Id); + var publishedMedia = PublishedMediaTests.GetNode(mRoot.Id, GetUmbracoContext("/test", 1234)); + + Assert.AreEqual(mRoot.Id, publishedMedia.Id); + Assert.AreEqual(mRoot.CreateDateTime.ToString("dd/MM/yyyy HH:mm:ss"), publishedMedia.CreateDate.ToString("dd/MM/yyyy HH:mm:ss")); + Assert.AreEqual(mRoot.User.Id, publishedMedia.CreatorId); + Assert.AreEqual(mRoot.User.Name, publishedMedia.CreatorName); + Assert.AreEqual(mRoot.ContentType.Alias, publishedMedia.DocumentTypeAlias); + Assert.AreEqual(mRoot.ContentType.Id, publishedMedia.DocumentTypeId); + Assert.AreEqual(mRoot.Level, publishedMedia.Level); + Assert.AreEqual(mRoot.Text, publishedMedia.Name); + Assert.AreEqual(mRoot.Path, publishedMedia.Path); + Assert.AreEqual(mRoot.sortOrder, publishedMedia.SortOrder); + Assert.IsNull(publishedMedia.Parent); + } + [TestCase("id")] [TestCase("nodeId")] [TestCase("__NodeId")] diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs index d62131c3f2..bf3a410e51 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs @@ -11,7 +11,7 @@ using Umbraco.Web; namespace Umbraco.Tests.PublishedContent { /// - /// Tests the typed extension methods on IPublishedContent the same way we test the dynamic ones + /// Tests the methods on IPublishedContent using the DefaultPublishedContentStore /// [TestFixture] public class PublishedContentTests : BaseWebTest diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs new file mode 100644 index 0000000000..a5a33db6a2 --- /dev/null +++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs @@ -0,0 +1,122 @@ +using System; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.Models; +using Umbraco.Core.PropertyEditors; +using Umbraco.Tests.TestHelpers; +using Umbraco.Web; +using umbraco.BusinessLogic; +using System.Linq; + +namespace Umbraco.Tests.PublishedContent +{ + /// + /// Tests the typed extension methods on IPublishedContent using the DefaultPublishedMediaStore + /// + [TestFixture] + public class PublishedMediaTests : BaseWebTest + { + + public override void Initialize() + { + base.Initialize(); + DoInitialization(GetUmbracoContext("/test", 1234)); + } + + /// + /// Shared with PublishMediaStoreTests + /// + /// + internal static void DoInitialization(UmbracoContext umbContext) + { + PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver( + new[] + { + typeof(DatePickerPropertyEditorValueConverter), + typeof(TinyMcePropertyEditorValueConverter), + typeof(YesNoPropertyEditorValueConverter) + }); + + //need to specify a custom callback for unit tests + PublishedContentHelper.GetDataTypeCallback = (docTypeAlias, propertyAlias) => + { + if (propertyAlias == "content") + { + //return the rte type id + return Guid.Parse("5e9b75ae-face-41c8-b47e-5f4b0fd82f83"); + } + return Guid.Empty; + }; + + UmbracoSettings.ForceSafeAliases = true; + UmbracoSettings.UmbracoLibraryCacheDuration = 1800; + + UmbracoContext.Current = umbContext; + PublishedMediaStoreResolver.Current = new PublishedMediaStoreResolver(new DefaultPublishedMediaStore()); + + UmbracoSettings.ForceSafeAliases = true; + } + + public override void TearDown() + { + base.TearDown(); + + DoTearDown(); + } + + /// + /// Shared with PublishMediaStoreTests + /// + internal static void DoTearDown() + { + PropertyEditorValueConvertersResolver.Reset(); + UmbracoContext.Current = null; + PublishedMediaStoreResolver.Reset(); + } + + /// + /// Shared with PublishMediaStoreTests + /// + /// + /// + /// + internal static IPublishedContent GetNode(int id, UmbracoContext umbracoContext) + { + var ctx = umbracoContext; + var mediaStore = new DefaultPublishedMediaStore(); + var doc = mediaStore.GetDocumentById(ctx, id); + Assert.IsNotNull(doc); + return doc; + } + + private IPublishedContent GetNode(int id) + { + return GetNode(id, GetUmbracoContext("/test", 1234)); + } + + [Test] + public void Children_Without_Examine() + { + var user = new User(0); + var mType = global::umbraco.cms.businesslogic.media.MediaType.MakeNew(user, "TestMediaType"); + var mRoot = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot", mType, user, -1); + + var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot.Id); + var mChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child2", mType, user, mRoot.Id); + var mChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child3", mType, user, mRoot.Id); + + var mSubChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild1", mType, user, mChild1.Id); + var mSubChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild2", mType, user, mChild1.Id); + var mSubChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild3", mType, user, mChild1.Id); + + var publishedMedia = GetNode(mRoot.Id); + var rootChildren = publishedMedia.Children(); + Assert.IsTrue(rootChildren.Select(x => x.Id).ContainsAll(new[] {mChild1.Id, mChild2.Id, mChild3.Id})); + + var publishedChild1 = GetNode(mChild1.Id); + var subChildren = publishedChild1.Children(); + Assert.IsTrue(subChildren.Select(x => x.Id).ContainsAll(new[] { mSubChild1.Id, mSubChild2.Id, mSubChild3.Id })); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs index 4cb5ad9c11..3a404347f0 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs @@ -4,6 +4,7 @@ using System.Web.Routing; using System.Xml; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.ObjectResolution; using Umbraco.Tests.Stubs; @@ -41,6 +42,7 @@ namespace Umbraco.Tests.TestHelpers public virtual void TearDown() { //reset the app context + ApplicationContext.ApplicationCache.ClearAllCache(); ApplicationContext.Current = null; Resolution.IsFrozen = false; if (RequiresDbSetup) @@ -49,6 +51,8 @@ namespace Umbraco.Tests.TestHelpers AppDomain.CurrentDomain.SetData("DataDirectory", null); Cache.ClearAllCache(); + + UmbracoSettings.ResetSetters(); } /// diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 146dfad43d..72528a7163 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -58,6 +58,7 @@ + diff --git a/src/Umbraco.Tests/UriUtilityTests.cs b/src/Umbraco.Tests/UriUtilityTests.cs index 6328c9ba12..a477d668d8 100644 --- a/src/Umbraco.Tests/UriUtilityTests.cs +++ b/src/Umbraco.Tests/UriUtilityTests.cs @@ -1,6 +1,7 @@ using System; using System.Configuration; using NUnit.Framework; +using Umbraco.Core.Configuration; using Umbraco.Web; namespace Umbraco.Tests @@ -10,6 +11,13 @@ namespace Umbraco.Tests [TestFixture] public class UriUtilityTests { + + [TearDown] + public void TearDown() + { + UmbracoSettings.ResetSetters(); + } + // test normal urls [TestCase("http://LocalHost/", "http://localhost/")] [TestCase("http://LocalHost/?x=y", "http://localhost/?x=y")] diff --git a/src/Umbraco.Web/DefaultPublishedMediaStore.cs b/src/Umbraco.Web/DefaultPublishedMediaStore.cs index dde6248565..562bfd91e5 100644 --- a/src/Umbraco.Web/DefaultPublishedMediaStore.cs +++ b/src/Umbraco.Web/DefaultPublishedMediaStore.cs @@ -41,37 +41,52 @@ namespace Umbraco.Web return result; } - private IPublishedContent GetUmbracoMedia(int id) + private ExamineManager GetExamineManagerSafe() { - try { - //first check in Examine as this is WAY faster - var criteria = ExamineManager.Instance - .SearchProviderCollection["InternalSearcher"] - .CreateSearchCriteria("media"); - var filter = criteria.Id(id); - var results = ExamineManager - .Instance.SearchProviderCollection["InternalSearcher"] - .Search(filter.Compile()); - if (results.Any()) - { - return ConvertFromSearchResult(results.First()); - } + return ExamineManager.Instance; } - catch (FileNotFoundException) + catch (TypeInitializationException) { - //Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco - //See this thread: http://examine.cdodeplex.com/discussions/264341 - //Catch the exception here for the time being, and just fallback to GetMedia - //TODO: Need to fix examine in LB scenarios! + return null; + } + } + + private IPublishedContent GetUmbracoMedia(int id) + { + var eMgr = GetExamineManagerSafe(); + if (eMgr != null) + { + try + { + //first check in Examine as this is WAY faster + var criteria = eMgr + .SearchProviderCollection["InternalSearcher"] + .CreateSearchCriteria("media"); + var filter = criteria.Id(id); + var results = eMgr + .SearchProviderCollection["InternalSearcher"] + .Search(filter.Compile()); + if (results.Any()) + { + return ConvertFromSearchResult(results.First()); + } + } + catch (FileNotFoundException) + { + //Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco + //See this thread: http://examine.cdodeplex.com/discussions/264341 + //Catch the exception here for the time being, and just fallback to GetMedia + //TODO: Need to fix examine in LB scenarios! + } } var media = global::umbraco.library.GetMedia(id, true); if (media != null && media.Current != null) { - if (media.MoveNext()) - { + //if (media.MoveNext()) + //{ var current = media.Current; //error check if (media.Current.MoveToFirstChild() && media.Current.Name.InvariantEquals("error")) @@ -80,7 +95,7 @@ namespace Umbraco.Web } return ConvertFromXPathNavigator(current); - } + //} } return null; @@ -240,27 +255,32 @@ namespace Umbraco.Web //if there is no navigator, try examine first, then re-look it up if (xpath == null) { - try + var eMgr = GetExamineManagerSafe(); + + if (eMgr != null) { - //first check in Examine as this is WAY faster - var criteria = ExamineManager.Instance - .SearchProviderCollection["InternalSearcher"] - .CreateSearchCriteria("media"); - var filter = criteria.ParentId(parentId); - var results = ExamineManager - .Instance.SearchProviderCollection["InternalSearcher"] - .Search(filter.Compile()); - if (results.Any()) + try { - return results.Select(ConvertFromSearchResult); + //first check in Examine as this is WAY faster + var criteria = eMgr + .SearchProviderCollection["InternalSearcher"] + .CreateSearchCriteria("media"); + var filter = criteria.ParentId(parentId); + var results = eMgr + .SearchProviderCollection["InternalSearcher"] + .Search(filter.Compile()); + if (results.Any()) + { + return results.Select(ConvertFromSearchResult); + } } - } - catch (FileNotFoundException) - { - //Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco - //See this thread: http://examine.cdodeplex.com/discussions/264341 - //Catch the exception here for the time being, and just fallback to GetMedia - } + catch (FileNotFoundException) + { + //Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco + //See this thread: http://examine.cdodeplex.com/discussions/264341 + //Catch the exception here for the time being, and just fallback to GetMedia + } + } var media = library.GetMedia(parentId, true); if (media != null && media.Current != null)