From 6a8c7d1a3bf1323323bcae8e0caefbe2bd56cd82 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 19 Dec 2018 17:13:46 +1100 Subject: [PATCH] Writes some tests, fixes a bug, orders results, writes notes --- .../Routing/GetContentUrlsTests.cs | 136 ++++++++++++++++++ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + .../Routing/UrlProviderExtensions.cs | 7 +- 3 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 src/Umbraco.Tests/Routing/GetContentUrlsTests.cs diff --git a/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs b/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs new file mode 100644 index 0000000000..a2a627227e --- /dev/null +++ b/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs @@ -0,0 +1,136 @@ +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using Moq; +using NUnit.Framework; +using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Models; +using Umbraco.Core.Services; +using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Web.Routing; + +namespace Umbraco.Tests.Routing +{ + [TestFixture] + public class GetContentUrlsTests : UrlRoutingTestBase + { + private IUmbracoSettingsSection _umbracoSettings; + + public override void SetUp() + { + base.SetUp(); + + //generate new mock settings and assign so we can configure in individual tests + _umbracoSettings = SettingsForTests.GenerateMockUmbracoSettings(); + SettingsForTests.ConfigureSettings(_umbracoSettings); + } + + private ILocalizedTextService GetTextService() + { + var textService = Mock.Of( + x => x.Localize("content/itemNotPublished", + It.IsAny(), + It.IsAny>()) == "content/itemNotPublished"); + return textService; + } + + private ILocalizationService GetLangService(params string[] isoCodes) + { + var allLangs = isoCodes + .Select(CultureInfo.GetCultureInfo) + .Select(culture => new Language(culture.Name) + { + CultureName = culture.DisplayName, + IsDefault = true, + IsMandatory = true + }).ToArray(); + + var langService = Mock.Of(x => x.GetAllLanguages() == allLangs); + return langService; + } + + [Test] + public void Content_Not_Published() + { + var contentType = MockedContentTypes.CreateBasicContentType(); + var content = MockedContent.CreateBasicContent(contentType); + content.Id = 1046; //fixme: we are using this ID only because it's built into the test XML published cache + content.Path = "-1,1046"; + + var umbContext = GetUmbracoContext("http://localhost:8000"); + var publishedRouter = CreatePublishedRouter(Container, + contentFinders: new ContentFinderCollection(new[] { new ContentFinderByUrl(Logger) })); + var urls = content.GetContentUrls(publishedRouter, + umbContext, + GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, + Logger).ToList(); + + Assert.AreEqual(1, urls.Count); + Assert.AreEqual("content/itemNotPublished", urls[0].Text); + Assert.IsFalse(urls[0].IsUrl); + } + + [Test] + public void Invariant_Root_Content_Published_No_Domains() + { + var contentType = MockedContentTypes.CreateBasicContentType(); + var content = MockedContent.CreateBasicContent(contentType); + content.Id = 1046; //fixme: we are using this ID only because it's built into the test XML published cache + content.Path = "-1,1046"; + content.Published = true; + + var umbContext = GetUmbracoContext("http://localhost:8000", + urlProviders: new []{ new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper()) }); + var publishedRouter = CreatePublishedRouter(Container, + contentFinders:new ContentFinderCollection(new[]{new ContentFinderByUrl(Logger) })); + var urls = content.GetContentUrls(publishedRouter, + umbContext, + GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, + Logger).ToList(); + + Assert.AreEqual(1, urls.Count); + Assert.AreEqual("/home/", urls[0].Text); + Assert.AreEqual("en-US", urls[0].Culture); + Assert.IsTrue(urls[0].IsUrl); + } + + [Test] + public void Invariant_Child_Content_Published_No_Domains() + { + var contentType = MockedContentTypes.CreateBasicContentType(); + var parent = MockedContent.CreateBasicContent(contentType); + parent.Id = 1046; //fixme: we are using this ID only because it's built into the test XML published cache + parent.Name = "home"; + parent.Path = "-1,1046"; + parent.Published = true; + var child = MockedContent.CreateBasicContent(contentType); + child.Name = "sub1"; + child.Id = 1173; //fixme: we are using this ID only because it's built into the test XML published cache + child.Path = "-1,1046,1173"; + child.Published = true; + + var umbContext = GetUmbracoContext("http://localhost:8000", + urlProviders: new[] { new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper()) }); + var publishedRouter = CreatePublishedRouter(Container, + contentFinders: new ContentFinderCollection(new[] { new ContentFinderByUrl(Logger) })); + var urls = child.GetContentUrls(publishedRouter, + umbContext, + GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, + Logger).ToList(); + + Assert.AreEqual(1, urls.Count); + Assert.AreEqual("/home/sub1/", urls[0].Text); + Assert.AreEqual("en-US", urls[0].Culture); + Assert.IsTrue(urls[0].IsUrl); + } + + //TODO: We need a lot of tests here, the above was just to get started with being able to unit test this method + // * variant URLs without domains assigned, what happens? + // * variant URLs with domains assigned, but also having more languages installed than there are domains/cultures assigned + // * variant URLs with an ancestor culture unpublished + // * invariant URLs with ancestors as variants + // * ... probably a lot more + + } +} diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index baeb667fcc..ed2324e02c 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -132,6 +132,7 @@ + diff --git a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs index 71a0c294ab..de9314704b 100644 --- a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs +++ b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs @@ -35,7 +35,10 @@ namespace Umbraco.Web.Routing if (logger == null) throw new ArgumentNullException(nameof(logger)); if (content.Published == false) + { yield return UrlInfo.Message(textService.Localize("content/itemNotPublished")); + yield break; + } var urls = new HashSet(); @@ -65,13 +68,13 @@ namespace Umbraco.Web.Routing // * The entire branch is invariant // * If there are less domain/cultures assigned to the branch than the number of cultures/languages installed - foreach (var dUrl in urlGroup.DistinctBy(x => x.Text.ToUpperInvariant())) + foreach (var dUrl in urlGroup.DistinctBy(x => x.Text.ToUpperInvariant()).OrderBy(x => x.Text).ThenBy(x => x.Culture)) yield return dUrl; } // get the 'other' urls - ie not what you'd get with GetUrl() but urls that would route to the document, nevertheless. // for these 'other' urls, we don't check whether they are routable, collide, anything - we just report them. - foreach (var otherUrl in umbracoContext.UrlProvider.GetOtherUrls(content.Id)) + foreach (var otherUrl in umbracoContext.UrlProvider.GetOtherUrls(content.Id).OrderBy(x => x.Text).ThenBy(x => x.Culture)) if (urls.Add(otherUrl)) //avoid duplicates yield return otherUrl; }