From 2b8be2cf003be16fe60b0afc4bb4e0d9fdee98ef Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 17 Feb 2020 12:07:51 +0100 Subject: [PATCH] Netcore: Move files from Web/Routing to Abstractions/Routing (#7642) * AB4951 - Move routing files to abstractions * Changed UriUtility from static to instance * Moved more files from Routing in web to Abstractions * Moved UrlProvider to Abstractions * Moved PublishedRequest to Abstractions --- .../PublishedContentExtensions.cs | 42 +++++++++++++++ .../Routing/AliasUrlProvider.cs | 16 +++--- .../Routing/ContentFinderByRedirectUrl.cs | 6 ++- .../Routing/ContentFinderByUrl.cs | 0 .../Routing/ContentFinderByUrlAlias.cs | 16 +++--- .../Routing/ContentFinderByUrlAndTemplate.cs | 12 +++-- .../Routing/ContentFinderCollection.cs | 0 .../Routing/ContentFinderCollectionBuilder.cs | 0 .../Routing/DefaultMediaUrlProvider.cs | 6 ++- .../Routing/DefaultUrlProvider.cs | 8 +-- .../Routing/EnsureRoutableOutcome.cs | 0 .../Routing/IContentFinder.cs | 0 .../Routing/IContentLastChanceFinder.cs | 0 .../Routing/IMediaUrlProvider.cs | 0 .../Routing/IPublishedRouter.cs | 0 .../Routing/IUrlProvider.cs | 0 .../Routing/MediaUrlProviderCollection.cs | 0 .../MediaUrlProviderCollectionBuilder.cs | 0 .../Routing/PublishedRequest.cs | 4 -- .../Routing/RoutableAttemptEventArgs.cs | 4 +- .../Routing/SiteDomainHelper.cs | 0 .../Routing/UmbracoRequestEventArgs.cs | 4 +- .../Routing}/UriUtility.cs | 40 ++++++++------- .../Routing/UrlProvider.cs | 3 +- .../Routing/UrlProviderCollection.cs | 0 .../Routing/UrlProviderCollectionBuilder.cs | 0 .../Routing/UrlProviderExtensions.cs | 15 +++--- .../Runtime/CoreInitialComposer.cs | 2 + .../Cache/DistributedCacheBinderTests.cs | 3 +- .../PublishedContentCacheTests.cs | 3 +- src/Umbraco.Tests/Misc/UriUtilityTests.cs | 2 + .../PublishedContentSnapshotTestBase.cs | 3 +- .../Routing/ContentFinderByAliasTests.cs | 3 +- .../ContentFinderByAliasWithDomainsTests.cs | 16 ++++-- .../ContentFinderByUrlAndTemplateTests.cs | 2 +- .../Routing/GetContentUrlsTests.cs | 15 ++++-- .../Routing/MediaUrlProviderTests.cs | 2 +- .../Routing/UmbracoModuleTests.cs | 3 +- src/Umbraco.Tests/Routing/UrlProviderTests.cs | 16 +++--- .../Routing/UrlsProviderWithDomainsTests.cs | 22 ++++---- .../Routing/UrlsWithNestedDomains.cs | 2 +- .../Scoping/ScopedNuCacheTests.cs | 3 +- .../Security/BackOfficeCookieManagerTests.cs | 4 +- .../TestControllerActivatorBase.cs | 3 +- src/Umbraco.Tests/TestHelpers/TestHelper.cs | 2 + .../TestHelpers/TestObjects-Mocks.cs | 3 +- .../TestHelpers/TestWithDatabaseBase.cs | 3 +- .../Objects/TestUmbracoContextFactory.cs | 3 +- src/Umbraco.Tests/Testing/UmbracoTestBase.cs | 14 ++--- ...RenderIndexActionSelectorAttributeTests.cs | 12 +++-- .../Web/Mvc/SurfaceControllerTests.cs | 12 +++-- .../Web/Mvc/UmbracoViewPageTests.cs | 3 +- .../Web/WebExtensionMethodTests.cs | 9 ++-- .../PublishedContentHashtableConverter.cs | 3 +- .../Models/Mapping/ContentMapDefinition.cs | 6 ++- src/Umbraco.Web/Net/AspNetIpResolver.cs | 2 +- src/Umbraco.Web/PublishedContentExtensions.cs | 51 ++++++++----------- src/Umbraco.Web/Umbraco.Web.csproj | 26 ---------- src/Umbraco.Web/UmbracoContext.cs | 7 ++- src/Umbraco.Web/UmbracoContextFactory.cs | 17 ++++++- src/Umbraco.Web/UmbracoInjectedModule.cs | 13 +++-- 61 files changed, 273 insertions(+), 193 deletions(-) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/AliasUrlProvider.cs (85%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/ContentFinderByRedirectUrl.cs (90%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/ContentFinderByUrl.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/ContentFinderByUrlAlias.cs (81%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/ContentFinderByUrlAndTemplate.cs (87%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/ContentFinderCollection.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/ContentFinderCollectionBuilder.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/DefaultMediaUrlProvider.cs (93%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/DefaultUrlProvider.cs (95%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/EnsureRoutableOutcome.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/IContentFinder.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/IContentLastChanceFinder.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/IMediaUrlProvider.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/IPublishedRouter.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/IUrlProvider.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/MediaUrlProviderCollection.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/MediaUrlProviderCollectionBuilder.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/PublishedRequest.cs (99%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/RoutableAttemptEventArgs.cs (79%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/SiteDomainHelper.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/UmbracoRequestEventArgs.cs (76%) rename src/{Umbraco.Web => Umbraco.Abstractions/Routing}/UriUtility.cs (84%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/UrlProvider.cs (98%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/UrlProviderCollection.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/UrlProviderCollectionBuilder.cs (100%) rename src/{Umbraco.Web => Umbraco.Abstractions}/Routing/UrlProviderExtensions.cs (95%) diff --git a/src/Umbraco.Abstractions/PublishedContentExtensions.cs b/src/Umbraco.Abstractions/PublishedContentExtensions.cs index aa432459dd..2b02456cdd 100644 --- a/src/Umbraco.Abstractions/PublishedContentExtensions.cs +++ b/src/Umbraco.Abstractions/PublishedContentExtensions.cs @@ -1,9 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; +using Umbraco.Composing; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Services; using Umbraco.Web.PublishedCache; +using Umbraco.Web.Routing; namespace Umbraco.Core { @@ -144,6 +147,14 @@ namespace Umbraco.Core return template == null ? string.Empty : template.Alias; } + public static bool IsAllowedTemplate(this IPublishedContent content, IContentTypeService contentTypeService, + IUmbracoSettingsSection umbracoSettingsSection, int templateId) + { + return content.IsAllowedTemplate(contentTypeService, + umbracoSettingsSection.WebRouting.DisableAlternativeTemplates, + umbracoSettingsSection.WebRouting.ValidateAlternativeTemplates, templateId); + } + public static bool IsAllowedTemplate(this IPublishedContent content, IContentTypeService contentTypeService, bool disableAlternativeTemplates, bool validateAlternativeTemplates, int templateId) { if (disableAlternativeTemplates) @@ -1075,5 +1086,36 @@ namespace Umbraco.Core } #endregion + + /// + /// Gets the url of the content item. + /// + /// + /// If the content item is a document, then this method returns the url of the + /// document. If it is a media, then this methods return the media url for the + /// 'umbracoFile' property. Use the MediaUrl() method to get the media url for other + /// properties. + /// The value of this property is contextual. It depends on the 'current' request uri, + /// if any. In addition, when the content type is multi-lingual, this is the url for the + /// specified culture. Otherwise, it is the invariant url. + /// + public static string Url(this IPublishedContent content, IPublishedUrlProvider publishedUrlProvider, string culture = null, UrlMode mode = UrlMode.Default) + { + if (publishedUrlProvider == null) + throw new InvalidOperationException("Cannot resolve a Url when Current.UmbracoContext.UrlProvider is null."); + + switch (content.ContentType.ItemType) + { + case PublishedItemType.Content: + return publishedUrlProvider.GetUrl(content, mode, culture); + + case PublishedItemType.Media: + return publishedUrlProvider.GetMediaUrl(content, mode, culture, Constants.Conventions.Media.File); + + default: + throw new NotSupportedException(); + } + } + } } diff --git a/src/Umbraco.Web/Routing/AliasUrlProvider.cs b/src/Umbraco.Abstractions/Routing/AliasUrlProvider.cs similarity index 85% rename from src/Umbraco.Web/Routing/AliasUrlProvider.cs rename to src/Umbraco.Abstractions/Routing/AliasUrlProvider.cs index 849a85dd2c..b9ae2a8db0 100644 --- a/src/Umbraco.Web/Routing/AliasUrlProvider.cs +++ b/src/Umbraco.Abstractions/Routing/AliasUrlProvider.cs @@ -16,12 +16,16 @@ namespace Umbraco.Web.Routing private readonly IGlobalSettings _globalSettings; private readonly IRequestHandlerSection _requestConfig; private readonly ISiteDomainHelper _siteDomainHelper; + private readonly UriUtility _uriUtility; + private readonly IPublishedValueFallback _publishedValueFallback; - public AliasUrlProvider(IGlobalSettings globalSettings, IRequestHandlerSection requestConfig, ISiteDomainHelper siteDomainHelper) + public AliasUrlProvider(IGlobalSettings globalSettings, IRequestHandlerSection requestConfig, ISiteDomainHelper siteDomainHelper, UriUtility uriUtility, IPublishedValueFallback publishedValueFallback) { _globalSettings = globalSettings; _requestConfig = requestConfig; _siteDomainHelper = siteDomainHelper; + _uriUtility = uriUtility; + _publishedValueFallback = publishedValueFallback; } // note - at the moment we seem to accept pretty much anything as an alias @@ -83,7 +87,7 @@ namespace Umbraco.Web.Routing if (varies) yield break; - var umbracoUrlName = node.Value(Constants.Conventions.Content.UrlAlias); + var umbracoUrlName = node.Value(_publishedValueFallback, Constants.Conventions.Content.UrlAlias); var aliases = umbracoUrlName?.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (aliases == null || aliases.Any() == false) @@ -93,7 +97,7 @@ namespace Umbraco.Web.Routing { var path = "/" + alias; var uri = new Uri(path, UriKind.Relative); - yield return UrlInfo.Url(UriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString()); + yield return UrlInfo.Url(_uriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString()); } } else @@ -108,8 +112,8 @@ namespace Umbraco.Web.Routing if (varies && !node.HasCulture(domainUri.Culture.Name)) continue; var umbracoUrlName = varies - ? node.Value(Constants.Conventions.Content.UrlAlias, culture: domainUri.Culture.Name) - : node.Value(Constants.Conventions.Content.UrlAlias); + ? node.Value(_publishedValueFallback,Constants.Conventions.Content.UrlAlias, culture: domainUri.Culture.Name) + : node.Value(_publishedValueFallback, Constants.Conventions.Content.UrlAlias); var aliases = umbracoUrlName?.Split(new [] {','}, StringSplitOptions.RemoveEmptyEntries); @@ -120,7 +124,7 @@ namespace Umbraco.Web.Routing { var path = "/" + alias; var uri = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path)); - yield return UrlInfo.Url(UriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString(), domainUri.Culture.Name); + yield return UrlInfo.Url(_uriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString(), domainUri.Culture.Name); } } } diff --git a/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs b/src/Umbraco.Abstractions/Routing/ContentFinderByRedirectUrl.cs similarity index 90% rename from src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderByRedirectUrl.cs index 9a8c1d2729..dffecd021e 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs +++ b/src/Umbraco.Abstractions/Routing/ContentFinderByRedirectUrl.cs @@ -17,11 +17,13 @@ namespace Umbraco.Web.Routing { private readonly IRedirectUrlService _redirectUrlService; private readonly ILogger _logger; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; - public ContentFinderByRedirectUrl(IRedirectUrlService redirectUrlService, ILogger logger) + public ContentFinderByRedirectUrl(IRedirectUrlService redirectUrlService, ILogger logger, IUmbracoContextAccessor umbracoContextAccessor) { _redirectUrlService = redirectUrlService; _logger = logger; + _umbracoContextAccessor = umbracoContextAccessor; } /// @@ -45,7 +47,7 @@ namespace Umbraco.Web.Routing } var content = frequest.UmbracoContext.Content.GetById(redirectUrl.ContentId); - var url = content == null ? "#" : content.Url(redirectUrl.Culture); + var url = content == null ? "#" : content.Url(_umbracoContextAccessor.UmbracoContext.UrlProvider, redirectUrl.Culture); if (url.StartsWith("#")) { _logger.Debug("Route {Route} matches content {ContentId} which has no url.", route, redirectUrl.ContentId); diff --git a/src/Umbraco.Web/Routing/ContentFinderByUrl.cs b/src/Umbraco.Abstractions/Routing/ContentFinderByUrl.cs similarity index 100% rename from src/Umbraco.Web/Routing/ContentFinderByUrl.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderByUrl.cs diff --git a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs b/src/Umbraco.Abstractions/Routing/ContentFinderByUrlAlias.cs similarity index 81% rename from src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderByUrlAlias.cs index ae435eff87..6bc1b329ed 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs +++ b/src/Umbraco.Abstractions/Routing/ContentFinderByUrlAlias.cs @@ -18,10 +18,14 @@ namespace Umbraco.Web.Routing /// public class ContentFinderByUrlAlias : IContentFinder { + private readonly IPublishedValueFallback _publishedValueFallback; + private readonly IVariationContextAccessor _variationContextAccessor; protected ILogger Logger { get; } - public ContentFinderByUrlAlias(ILogger logger) + public ContentFinderByUrlAlias(ILogger logger, IPublishedValueFallback publishedValueFallback, IVariationContextAccessor variationContextAccessor) { + _publishedValueFallback = publishedValueFallback; + _variationContextAccessor = variationContextAccessor; Logger = logger; } @@ -51,7 +55,7 @@ namespace Umbraco.Web.Routing return node != null; } - private static IPublishedContent FindContentByAlias(IPublishedContentCache cache, int rootNodeId, string culture, string alias) + private IPublishedContent FindContentByAlias(IPublishedContentCache cache, int rootNodeId, string culture, string alias) { if (alias == null) throw new ArgumentNullException(nameof(alias)); @@ -84,11 +88,11 @@ namespace Umbraco.Web.Routing if (varies) { if (!c.HasCulture(culture)) return false; - v = c.Value(propertyAlias, culture); + v = c.Value(_publishedValueFallback, propertyAlias, culture); } else { - v = c.Value(propertyAlias); + v = c.Value(_publishedValueFallback, propertyAlias); } if (string.IsNullOrWhiteSpace(v)) return false; v = "," + v.Replace(" ", "") + ","; @@ -101,12 +105,12 @@ namespace Umbraco.Web.Routing if (rootNodeId > 0) { var rootNode = cache.GetById(rootNodeId); - return rootNode?.Descendants().FirstOrDefault(x => IsMatch(x, test1, test2)); + return rootNode?.Descendants(_variationContextAccessor).FirstOrDefault(x => IsMatch(x, test1, test2)); } foreach (var rootContent in cache.GetAtRoot()) { - var c = rootContent.DescendantsOrSelf().FirstOrDefault(x => IsMatch(x, test1, test2)); + var c = rootContent.DescendantsOrSelf(_variationContextAccessor).FirstOrDefault(x => IsMatch(x, test1, test2)); if (c != null) return c; } diff --git a/src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs b/src/Umbraco.Abstractions/Routing/ContentFinderByUrlAndTemplate.cs similarity index 87% rename from src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderByUrlAndTemplate.cs index 84529dfaa1..933ab47150 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs +++ b/src/Umbraco.Abstractions/Routing/ContentFinderByUrlAndTemplate.cs @@ -1,9 +1,7 @@ using Umbraco.Core.Logging; -using Umbraco.Core.Models; using Umbraco.Core; -using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Models.PublishedContent; -using Umbraco.Web.Composing; using Umbraco.Core.Services; namespace Umbraco.Web.Routing @@ -19,11 +17,15 @@ namespace Umbraco.Web.Routing public class ContentFinderByUrlAndTemplate : ContentFinderByUrl { private readonly IFileService _fileService; + private readonly IUmbracoSettingsSection _umbracoSettingsSection; + private readonly IContentTypeService _contentTypeService; - public ContentFinderByUrlAndTemplate(ILogger logger, IFileService fileService) + public ContentFinderByUrlAndTemplate(ILogger logger, IFileService fileService, IUmbracoSettingsSection umbracoSettingsSection, IContentTypeService contentTypeService) : base(logger) { _fileService = fileService; + _umbracoSettingsSection = umbracoSettingsSection; + _contentTypeService = contentTypeService; } /// @@ -73,7 +75,7 @@ namespace Umbraco.Web.Routing } // IsAllowedTemplate deals both with DisableAlternativeTemplates and ValidateAlternativeTemplates settings - if (!node.IsAllowedTemplate(template.Id)) + if (!node.IsAllowedTemplate(_contentTypeService, _umbracoSettingsSection, template.Id)) { Logger.Warn("Alternative template '{TemplateAlias}' is not allowed on node {NodeId}.", template.Alias, node.Id); frequest.PublishedContent = null; // clear diff --git a/src/Umbraco.Web/Routing/ContentFinderCollection.cs b/src/Umbraco.Abstractions/Routing/ContentFinderCollection.cs similarity index 100% rename from src/Umbraco.Web/Routing/ContentFinderCollection.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderCollection.cs diff --git a/src/Umbraco.Web/Routing/ContentFinderCollectionBuilder.cs b/src/Umbraco.Abstractions/Routing/ContentFinderCollectionBuilder.cs similarity index 100% rename from src/Umbraco.Web/Routing/ContentFinderCollectionBuilder.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderCollectionBuilder.cs diff --git a/src/Umbraco.Web/Routing/DefaultMediaUrlProvider.cs b/src/Umbraco.Abstractions/Routing/DefaultMediaUrlProvider.cs similarity index 93% rename from src/Umbraco.Web/Routing/DefaultMediaUrlProvider.cs rename to src/Umbraco.Abstractions/Routing/DefaultMediaUrlProvider.cs index c7c987e0e5..a9f78978d8 100644 --- a/src/Umbraco.Web/Routing/DefaultMediaUrlProvider.cs +++ b/src/Umbraco.Abstractions/Routing/DefaultMediaUrlProvider.cs @@ -11,10 +11,12 @@ namespace Umbraco.Web.Routing public class DefaultMediaUrlProvider : IMediaUrlProvider { private readonly PropertyEditorCollection _propertyEditors; + private readonly UriUtility _uriUtility; - public DefaultMediaUrlProvider(PropertyEditorCollection propertyEditors) + public DefaultMediaUrlProvider(PropertyEditorCollection propertyEditors, UriUtility uriUtility) { _propertyEditors = propertyEditors ?? throw new ArgumentNullException(nameof(propertyEditors)); + _uriUtility = uriUtility; } /// @@ -70,7 +72,7 @@ namespace Umbraco.Web.Routing throw new ArgumentOutOfRangeException(nameof(mode)); } - return UriUtility.MediaUriFromUmbraco(uri); + return _uriUtility.MediaUriFromUmbraco(uri); } } } diff --git a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs b/src/Umbraco.Abstractions/Routing/DefaultUrlProvider.cs similarity index 95% rename from src/Umbraco.Web/Routing/DefaultUrlProvider.cs rename to src/Umbraco.Abstractions/Routing/DefaultUrlProvider.cs index 43d4d5dd90..7ab73ab400 100644 --- a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs +++ b/src/Umbraco.Abstractions/Routing/DefaultUrlProvider.cs @@ -17,13 +17,15 @@ namespace Umbraco.Web.Routing private readonly ILogger _logger; private readonly IGlobalSettings _globalSettings; private readonly ISiteDomainHelper _siteDomainHelper; + private readonly UriUtility _uriUtility; - public DefaultUrlProvider(IRequestHandlerSection requestSettings, ILogger logger, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper) + public DefaultUrlProvider(IRequestHandlerSection requestSettings, ILogger logger, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper, UriUtility uriUtility) { _requestSettings = requestSettings; _logger = logger; _globalSettings = globalSettings; _siteDomainHelper = siteDomainHelper; + _uriUtility = uriUtility; } #region GetUrl @@ -108,7 +110,7 @@ namespace Umbraco.Web.Routing var path = pos == 0 ? route : route.Substring(pos); var uri = new Uri(CombinePaths(d.Uri.GetLeftPart(UriPartial.Path), path)); - uri = UriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings); + uri = _uriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings); yield return UrlInfo.Url(uri.ToString(), culture); } } @@ -167,7 +169,7 @@ namespace Umbraco.Web.Routing // UriFromUmbraco will handle vdir // meaning it will add vdir into domain urls too! - return UriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings); + return _uriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings); } string CombinePaths(string path1, string path2) diff --git a/src/Umbraco.Web/Routing/EnsureRoutableOutcome.cs b/src/Umbraco.Abstractions/Routing/EnsureRoutableOutcome.cs similarity index 100% rename from src/Umbraco.Web/Routing/EnsureRoutableOutcome.cs rename to src/Umbraco.Abstractions/Routing/EnsureRoutableOutcome.cs diff --git a/src/Umbraco.Web/Routing/IContentFinder.cs b/src/Umbraco.Abstractions/Routing/IContentFinder.cs similarity index 100% rename from src/Umbraco.Web/Routing/IContentFinder.cs rename to src/Umbraco.Abstractions/Routing/IContentFinder.cs diff --git a/src/Umbraco.Web/Routing/IContentLastChanceFinder.cs b/src/Umbraco.Abstractions/Routing/IContentLastChanceFinder.cs similarity index 100% rename from src/Umbraco.Web/Routing/IContentLastChanceFinder.cs rename to src/Umbraco.Abstractions/Routing/IContentLastChanceFinder.cs diff --git a/src/Umbraco.Web/Routing/IMediaUrlProvider.cs b/src/Umbraco.Abstractions/Routing/IMediaUrlProvider.cs similarity index 100% rename from src/Umbraco.Web/Routing/IMediaUrlProvider.cs rename to src/Umbraco.Abstractions/Routing/IMediaUrlProvider.cs diff --git a/src/Umbraco.Web/Routing/IPublishedRouter.cs b/src/Umbraco.Abstractions/Routing/IPublishedRouter.cs similarity index 100% rename from src/Umbraco.Web/Routing/IPublishedRouter.cs rename to src/Umbraco.Abstractions/Routing/IPublishedRouter.cs diff --git a/src/Umbraco.Web/Routing/IUrlProvider.cs b/src/Umbraco.Abstractions/Routing/IUrlProvider.cs similarity index 100% rename from src/Umbraco.Web/Routing/IUrlProvider.cs rename to src/Umbraco.Abstractions/Routing/IUrlProvider.cs diff --git a/src/Umbraco.Web/Routing/MediaUrlProviderCollection.cs b/src/Umbraco.Abstractions/Routing/MediaUrlProviderCollection.cs similarity index 100% rename from src/Umbraco.Web/Routing/MediaUrlProviderCollection.cs rename to src/Umbraco.Abstractions/Routing/MediaUrlProviderCollection.cs diff --git a/src/Umbraco.Web/Routing/MediaUrlProviderCollectionBuilder.cs b/src/Umbraco.Abstractions/Routing/MediaUrlProviderCollectionBuilder.cs similarity index 100% rename from src/Umbraco.Web/Routing/MediaUrlProviderCollectionBuilder.cs rename to src/Umbraco.Abstractions/Routing/MediaUrlProviderCollectionBuilder.cs diff --git a/src/Umbraco.Web/Routing/PublishedRequest.cs b/src/Umbraco.Abstractions/Routing/PublishedRequest.cs similarity index 99% rename from src/Umbraco.Web/Routing/PublishedRequest.cs rename to src/Umbraco.Abstractions/Routing/PublishedRequest.cs index 86bca12ef9..9b00e59deb 100644 --- a/src/Umbraco.Web/Routing/PublishedRequest.cs +++ b/src/Umbraco.Abstractions/Routing/PublishedRequest.cs @@ -2,12 +2,8 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Threading; -using System.Web; -using Umbraco.Core; -using Umbraco.Web.Composing; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; -using Umbraco.Web.Macros; using Umbraco.Core.Configuration.UmbracoSettings; namespace Umbraco.Web.Routing diff --git a/src/Umbraco.Web/Routing/RoutableAttemptEventArgs.cs b/src/Umbraco.Abstractions/Routing/RoutableAttemptEventArgs.cs similarity index 79% rename from src/Umbraco.Web/Routing/RoutableAttemptEventArgs.cs rename to src/Umbraco.Abstractions/Routing/RoutableAttemptEventArgs.cs index eea33f95fe..54ea98b3a4 100644 --- a/src/Umbraco.Web/Routing/RoutableAttemptEventArgs.cs +++ b/src/Umbraco.Abstractions/Routing/RoutableAttemptEventArgs.cs @@ -9,8 +9,8 @@ namespace Umbraco.Web.Routing { public EnsureRoutableOutcome Outcome { get; private set; } - public RoutableAttemptEventArgs(EnsureRoutableOutcome reason, IUmbracoContext umbracoContext, HttpContextBase httpContext) - : base(umbracoContext, httpContext) + public RoutableAttemptEventArgs(EnsureRoutableOutcome reason, IUmbracoContext umbracoContext) + : base(umbracoContext) { Outcome = reason; } diff --git a/src/Umbraco.Web/Routing/SiteDomainHelper.cs b/src/Umbraco.Abstractions/Routing/SiteDomainHelper.cs similarity index 100% rename from src/Umbraco.Web/Routing/SiteDomainHelper.cs rename to src/Umbraco.Abstractions/Routing/SiteDomainHelper.cs diff --git a/src/Umbraco.Web/Routing/UmbracoRequestEventArgs.cs b/src/Umbraco.Abstractions/Routing/UmbracoRequestEventArgs.cs similarity index 76% rename from src/Umbraco.Web/Routing/UmbracoRequestEventArgs.cs rename to src/Umbraco.Abstractions/Routing/UmbracoRequestEventArgs.cs index 56c9c9f07d..4430d9689f 100644 --- a/src/Umbraco.Web/Routing/UmbracoRequestEventArgs.cs +++ b/src/Umbraco.Abstractions/Routing/UmbracoRequestEventArgs.cs @@ -9,12 +9,10 @@ namespace Umbraco.Web.Routing public class UmbracoRequestEventArgs : EventArgs { public IUmbracoContext UmbracoContext { get; private set; } - public HttpContextBase HttpContext { get; private set; } - public UmbracoRequestEventArgs(IUmbracoContext umbracoContext, HttpContextBase httpContext) + public UmbracoRequestEventArgs(IUmbracoContext umbracoContext) { UmbracoContext = umbracoContext; - HttpContext = httpContext; } } } diff --git a/src/Umbraco.Web/UriUtility.cs b/src/Umbraco.Abstractions/Routing/UriUtility.cs similarity index 84% rename from src/Umbraco.Web/UriUtility.cs rename to src/Umbraco.Abstractions/Routing/UriUtility.cs index 6093d3e55a..11bb1dabfb 100644 --- a/src/Umbraco.Web/UriUtility.cs +++ b/src/Umbraco.Abstractions/Routing/UriUtility.cs @@ -4,21 +4,22 @@ using System.Web; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Hosting; namespace Umbraco.Web { - public static class UriUtility + public sealed class UriUtility { static string _appPath; static string _appPathPrefix; - static UriUtility() + public UriUtility(IHostingEnvironment hostingEnvironment) { - ResetAppDomainAppVirtualPath(); + ResetAppDomainAppVirtualPath(hostingEnvironment); } // internal for unit testing only - internal static void SetAppDomainAppVirtualPath(string appPath) + internal void SetAppDomainAppVirtualPath(string appPath) { _appPath = appPath ?? "/"; _appPathPrefix = _appPath; @@ -26,20 +27,20 @@ namespace Umbraco.Web _appPathPrefix = String.Empty; } - internal static void ResetAppDomainAppVirtualPath() + internal void ResetAppDomainAppVirtualPath(IHostingEnvironment hostingEnvironment) { - SetAppDomainAppVirtualPath(HttpRuntime.AppDomainAppVirtualPath); + SetAppDomainAppVirtualPath(hostingEnvironment.ApplicationVirtualPath); } // will be "/" or "/foo" - public static string AppPath => _appPath; + public string AppPath => _appPath; // will be "" or "/foo" - public static string AppPathPrefix => _appPathPrefix; + public string AppPathPrefix => _appPathPrefix; // adds the virtual directory if any // see also VirtualPathUtility.ToAbsolute - public static string ToAbsolute(string url) + public string ToAbsolute(string url) { //return ResolveUrl(url); url = url.TrimStart('~'); @@ -48,7 +49,7 @@ namespace Umbraco.Web // strips the virtual directory if any // see also VirtualPathUtility.ToAppRelative - public static string ToAppRelative(string virtualPath) + public string ToAppRelative(string virtualPath) { if (virtualPath.InvariantStartsWith(_appPathPrefix) && (virtualPath.Length == _appPathPrefix.Length || virtualPath[_appPathPrefix.Length] == '/')) @@ -60,7 +61,7 @@ namespace Umbraco.Web // maps an internal umbraco uri to a public uri // ie with virtual directory, .aspx if required... - public static Uri UriFromUmbraco(Uri uri, IGlobalSettings globalSettings, IRequestHandlerSection requestConfig) + public Uri UriFromUmbraco(Uri uri, IGlobalSettings globalSettings, IRequestHandlerSection requestConfig) { var path = uri.GetSafeAbsolutePath(); @@ -74,7 +75,7 @@ namespace Umbraco.Web // maps a media umbraco uri to a public uri // ie with virtual directory - that is all for media - public static Uri MediaUriFromUmbraco(Uri uri) + public Uri MediaUriFromUmbraco(Uri uri) { var path = uri.GetSafeAbsolutePath(); path = ToAbsolute(path); @@ -83,7 +84,7 @@ namespace Umbraco.Web // maps a public uri to an internal umbraco uri // ie no virtual directory, no .aspx, lowercase... - public static Uri UriToUmbraco(Uri uri) + public Uri UriToUmbraco(Uri uri) { // note: no need to decode uri here because we're returning a uri // so it will be re-encoded anyway @@ -120,7 +121,7 @@ namespace Umbraco.Web // ResolveUrl("page2.aspx") returns "/page2.aspx" // Page.ResolveUrl("page2.aspx") returns "/sub/page2.aspx" (relative...) // - public static string ResolveUrl(string relativeUrl) + public string ResolveUrl(string relativeUrl) { if (relativeUrl == null) throw new ArgumentNullException("relativeUrl"); @@ -182,21 +183,22 @@ namespace Umbraco.Web /// Returns an full url with the host, port, etc... /// /// An absolute path (i.e. starts with a '/' ) - /// + /// /// /// /// Based on http://stackoverflow.com/questions/3681052/get-absolute-url-from-relative-path-refactored-method /// - internal static Uri ToFullUrl(string absolutePath, HttpContextBase httpContext) + internal Uri ToFullUrl(string absolutePath, Uri curentRequestUrl) { - if (httpContext == null) throw new ArgumentNullException("httpContext"); if (string.IsNullOrEmpty(absolutePath)) - throw new ArgumentNullException("absolutePath"); + throw new ArgumentNullException(nameof(absolutePath)); if (!absolutePath.StartsWith("/")) throw new FormatException("The absolutePath specified does not start with a '/'"); - return new Uri(absolutePath, UriKind.Relative).MakeAbsolute(httpContext.Request.Url); + return new Uri(absolutePath, UriKind.Relative).MakeAbsolute(curentRequestUrl); } + + } } diff --git a/src/Umbraco.Web/Routing/UrlProvider.cs b/src/Umbraco.Abstractions/Routing/UrlProvider.cs similarity index 98% rename from src/Umbraco.Web/Routing/UrlProvider.cs rename to src/Umbraco.Abstractions/Routing/UrlProvider.cs index 2ce673dcce..29f0fb39d4 100644 --- a/src/Umbraco.Web/Routing/UrlProvider.cs +++ b/src/Umbraco.Abstractions/Routing/UrlProvider.cs @@ -4,7 +4,6 @@ using System.Linq; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core; using Umbraco.Core.Models.PublishedContent; -using Umbraco.Web.Composing; namespace Umbraco.Web.Routing { @@ -143,7 +142,7 @@ namespace Umbraco.Web.Routing var provider = _urlProviders.OfType().FirstOrDefault(); var url = provider == null ? route // what else? - : provider.GetUrlFromRoute(route, Current.UmbracoContext, id, _umbracoContext.CleanedUmbracoUrl, Mode, culture)?.Text; + : provider.GetUrlFromRoute(route, _umbracoContext, id, _umbracoContext.CleanedUmbracoUrl, Mode, culture)?.Text; return url ?? "#"; } diff --git a/src/Umbraco.Web/Routing/UrlProviderCollection.cs b/src/Umbraco.Abstractions/Routing/UrlProviderCollection.cs similarity index 100% rename from src/Umbraco.Web/Routing/UrlProviderCollection.cs rename to src/Umbraco.Abstractions/Routing/UrlProviderCollection.cs diff --git a/src/Umbraco.Web/Routing/UrlProviderCollectionBuilder.cs b/src/Umbraco.Abstractions/Routing/UrlProviderCollectionBuilder.cs similarity index 100% rename from src/Umbraco.Web/Routing/UrlProviderCollectionBuilder.cs rename to src/Umbraco.Abstractions/Routing/UrlProviderCollectionBuilder.cs diff --git a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs b/src/Umbraco.Abstractions/Routing/UrlProviderExtensions.cs similarity index 95% rename from src/Umbraco.Web/Routing/UrlProviderExtensions.cs rename to src/Umbraco.Abstractions/Routing/UrlProviderExtensions.cs index e4359ad03e..c3b71ac028 100644 --- a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs +++ b/src/Umbraco.Abstractions/Routing/UrlProviderExtensions.cs @@ -25,7 +25,8 @@ namespace Umbraco.Web.Routing ILocalizedTextService textService, IContentService contentService, IVariationContextAccessor variationContextAccessor, - ILogger logger) + ILogger logger, + UriUtility uriUtility) { if (content == null) throw new ArgumentNullException(nameof(content)); if (publishedRouter == null) throw new ArgumentNullException(nameof(publishedRouter)); @@ -34,6 +35,7 @@ namespace Umbraco.Web.Routing if (textService == null) throw new ArgumentNullException(nameof(textService)); if (contentService == null) throw new ArgumentNullException(nameof(contentService)); if (logger == null) throw new ArgumentNullException(nameof(logger)); + if (uriUtility == null) throw new ArgumentNullException(nameof(uriUtility)); if (variationContextAccessor == null) throw new ArgumentNullException(nameof(variationContextAccessor)); if (content.Published == false) @@ -59,7 +61,7 @@ namespace Umbraco.Web.Routing //get all URLs for all cultures //in a HashSet, so de-duplicates too - foreach (var cultureUrl in GetContentUrlsByCulture(content, cultures, publishedRouter, umbracoContext, contentService, textService, variationContextAccessor, logger)) + foreach (var cultureUrl in GetContentUrlsByCulture(content, cultures, publishedRouter, umbracoContext, contentService, textService, variationContextAccessor, logger, uriUtility)) { urls.Add(cultureUrl); } @@ -100,7 +102,8 @@ namespace Umbraco.Web.Routing IContentService contentService, ILocalizedTextService textService, IVariationContextAccessor variationContextAccessor, - ILogger logger) + ILogger logger, + UriUtility uriUtility) { foreach (var culture in cultures) { @@ -135,7 +138,7 @@ namespace Umbraco.Web.Routing // got a url, deal with collisions, add url default: - if (DetectCollision(content, url, culture, umbracoContext, publishedRouter, textService, variationContextAccessor, out var urlInfo)) // detect collisions, etc + if (DetectCollision(content, url, culture, umbracoContext, publishedRouter, textService, variationContextAccessor, uriUtility, out var urlInfo)) // detect collisions, etc yield return urlInfo; else yield return UrlInfo.Url(url, culture); @@ -165,12 +168,12 @@ namespace Umbraco.Web.Routing return UrlInfo.Message(textService.Localize("content/parentCultureNotPublished", new[] {parent.Name}), culture); } - private static bool DetectCollision(IContent content, string url, string culture, IUmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, IVariationContextAccessor variationContextAccessor, out UrlInfo urlInfo) + private static bool DetectCollision(IContent content, string url, string culture, IUmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, IVariationContextAccessor variationContextAccessor, UriUtility uriUtility, out UrlInfo urlInfo) { // test for collisions on the 'main' url var uri = new Uri(url.TrimEnd('/'), UriKind.RelativeOrAbsolute); if (uri.IsAbsoluteUri == false) uri = uri.MakeAbsolute(umbracoContext.CleanedUmbracoUrl); - uri = UriUtility.UriToUmbraco(uri); + uri = uriUtility.UriToUmbraco(uri); var pcr = publishedRouter.CreateRequest(umbracoContext, uri); publishedRouter.TryRouteRequest(pcr); diff --git a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs index dbecd56d18..30c88452a7 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs @@ -20,6 +20,7 @@ using Umbraco.Core.Serialization; using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Core.Sync; +using Umbraco.Web; using IntegerValidator = Umbraco.Core.PropertyEditors.Validators.IntegerValidator; namespace Umbraco.Core.Runtime @@ -137,6 +138,7 @@ namespace Umbraco.Core.Runtime composition.SetCultureDictionaryFactory(); composition.Register(f => f.GetInstance().CreateDictionary(), Lifetime.Singleton); + composition.RegisterUnique(); } } } diff --git a/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs b/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs index 5fe13f01aa..ab64a96a24 100644 --- a/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs +++ b/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs @@ -163,7 +163,8 @@ namespace Umbraco.Tests.Cache new UrlProviderCollection(Enumerable.Empty()), new MediaUrlProviderCollection(Enumerable.Empty()), Mock.Of(), - IOHelper); + IOHelper, + UriUtility); // just assert it does not throw var refreshers = new DistributedCacheBinder(null, umbracoContextFactory, null); diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs index 36d78adf10..6463569c0d 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs @@ -83,7 +83,8 @@ namespace Umbraco.Tests.Cache.PublishedCache Enumerable.Empty(), globalSettings, new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); _cache = _umbracoContext.Content; } diff --git a/src/Umbraco.Tests/Misc/UriUtilityTests.cs b/src/Umbraco.Tests/Misc/UriUtilityTests.cs index 33a4b45249..0d0f6db61e 100644 --- a/src/Umbraco.Tests/Misc/UriUtilityTests.cs +++ b/src/Umbraco.Tests/Misc/UriUtilityTests.cs @@ -12,6 +12,8 @@ namespace Umbraco.Tests.Misc [TestFixture] public class UriUtilityTests { + + public UriUtility UriUtility { get; } = TestHelper.UriUtility; [TearDown] public void TearDown() { diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs index a1592a57d0..ab0b8f3b1a 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs @@ -77,7 +77,8 @@ namespace Umbraco.Tests.PublishedContent Enumerable.Empty(), globalSettings, new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); return umbracoContext; } diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs index 8d0a544c06..c9d11055ac 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs @@ -48,7 +48,8 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(urlAsString); var publishedRouter = CreatePublishedRouter(); var frequest = publishedRouter.CreateRequest(umbracoContext); - var lookup = new ContentFinderByUrlAlias(Logger); + var lookup = + new ContentFinderByUrlAlias(Logger, Mock.Of(), VariationContextAccessor); var result = lookup.TryFindContent(frequest); diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs index 60ed41593d..1a08153b4f 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs @@ -20,10 +20,16 @@ namespace Umbraco.Tests.Routing var properties = new[] { - new PublishedPropertyType("umbracoUrlAlias", Constants.DataTypes.Textbox, false, ContentVariation.Nothing, - new PropertyValueConverterCollection(Enumerable.Empty()), - Mock.Of(), - Mock.Of()), + new PublishedPropertyType( + propertyTypeAlias:"umbracoUrlAlias", + dataTypeId: Constants.DataTypes.Textbox, + isUserProperty:false, + variations: ContentVariation.Nothing, + propertyValueConverters:new PropertyValueConverterCollection(Enumerable.Empty()), + contentType:Mock.Of(), + publishedModelFactory:Mock.Of(), + factory:Mock.Of() + ) }; _publishedContentType = new PublishedContentType(0, "Doc", PublishedItemType.Content, Enumerable.Empty(), properties, ContentVariation.Nothing); } @@ -57,7 +63,7 @@ namespace Umbraco.Tests.Routing if (expectedNode > 0) Assert.AreEqual(expectedCulture, request.Culture.Name); - var finder = new ContentFinderByUrlAlias(Logger); + var finder = new ContentFinderByUrlAlias(Logger, Mock.Of(), VariationContextAccessor); var result = finder.TryFindContent(request); if (expectedNode > 0) diff --git a/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs index f74c68777e..ba07bbed82 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs @@ -38,7 +38,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(urlAsString, template1.Id, globalSettings:globalSettings.Object); var publishedRouter = CreatePublishedRouter(); var frequest = publishedRouter.CreateRequest(umbracoContext); - var lookup = new ContentFinderByUrlAndTemplate(Logger, ServiceContext.FileService); + var lookup = new ContentFinderByUrlAndTemplate(Logger, ServiceContext.FileService, TestObjects.GetUmbracoSettings(), ServiceContext.ContentTypeService); var result = lookup.TryFindContent(frequest); diff --git a/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs b/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs index d6bd61dc8a..65fc139519 100644 --- a/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs +++ b/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs @@ -54,7 +54,8 @@ namespace Umbraco.Tests.Routing umbContext, GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, VariationContextAccessor, - Logger).ToList(); + Logger, + UriUtility).ToList(); Assert.AreEqual(1, urls.Count); Assert.AreEqual("content/itemNotPublished", urls[0].Text); @@ -73,13 +74,15 @@ namespace Umbraco.Tests.Routing var umbracoSettings = Current.Configs.Settings(); var umbContext = GetUmbracoContext("http://localhost:8000", - urlProviders: new []{ new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper()) }); + urlProviders: new []{ new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper(), UriUtility) }); var publishedRouter = CreatePublishedRouter(Factory, contentFinders:new ContentFinderCollection(new[]{new ContentFinderByUrl(Logger) })); var urls = content.GetContentUrls(publishedRouter, umbContext, GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, - VariationContextAccessor, Logger).ToList(); + VariationContextAccessor, + Logger, + UriUtility).ToList(); Assert.AreEqual(1, urls.Count); Assert.AreEqual("/home/", urls[0].Text); @@ -105,13 +108,15 @@ namespace Umbraco.Tests.Routing var umbracoSettings = Current.Configs.Settings(); var umbContext = GetUmbracoContext("http://localhost:8000", - urlProviders: new[] { new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper()) }); + urlProviders: new[] { new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper(), UriUtility) }); var publishedRouter = CreatePublishedRouter(Factory, contentFinders: new ContentFinderCollection(new[] { new ContentFinderByUrl(Logger) })); var urls = child.GetContentUrls(publishedRouter, umbContext, GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, - VariationContextAccessor, Logger).ToList(); + VariationContextAccessor, + Logger, + UriUtility).ToList(); Assert.AreEqual(1, urls.Count); Assert.AreEqual("/home/sub1/", urls[0].Text); diff --git a/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs b/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs index 78ff71678d..638830b12a 100644 --- a/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs +++ b/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs @@ -41,7 +41,7 @@ namespace Umbraco.Tests.Routing new FileUploadPropertyEditor(logger, mediaFileSystemMock, contentSection, dataTypeService, LocalizationService, LocalizedTextService, ShortStringHelper, umbracoSettingsSection), new ImageCropperPropertyEditor(logger, mediaFileSystemMock, contentSection, dataTypeService, LocalizationService, IOHelper, ShortStringHelper, LocalizedTextService, umbracoSettingsSection), })); - _mediaUrlProvider = new DefaultMediaUrlProvider(propertyEditors); + _mediaUrlProvider = new DefaultMediaUrlProvider(propertyEditors, UriUtility); } public override void TearDown() diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs index d4c242a762..2874e51edd 100644 --- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs +++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs @@ -42,7 +42,8 @@ namespace Umbraco.Tests.Routing logger, null, // FIXME: PublishedRouter complexities... Mock.Of(), - new RoutableDocumentFilter(globalSettings, IOHelper) + new RoutableDocumentFilter(globalSettings, IOHelper), + UriUtility ); runtime.Level = RuntimeLevel.Run; diff --git a/src/Umbraco.Tests/Routing/UrlProviderTests.cs b/src/Umbraco.Tests/Routing/UrlProviderTests.cs index 1cecf74c3f..58faeb1f30 100644 --- a/src/Umbraco.Tests/Routing/UrlProviderTests.cs +++ b/src/Umbraco.Tests/Routing/UrlProviderTests.cs @@ -48,7 +48,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, urlProviders: new[] { - new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings: globalSettings.Object); var requestHandlerMock = Mock.Get(umbracoSettings.RequestHandler); @@ -111,7 +111,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, urlProviders: new[] { - new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings: globalSettings.Object); @@ -139,7 +139,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, urlProviders: new[] { - new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings: globalSettings.Object); @@ -179,7 +179,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(currentUri, umbracoSettings: umbracoSettings, urlProviders: new[] { - new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings: globalSettings.Object, snapshotService: snapshotService.Object); @@ -233,7 +233,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(currentUri, umbracoSettings: umbracoSettings, urlProviders: new[] { - new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings: globalSettings.Object, snapshotService: snapshotService.Object); @@ -287,7 +287,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(currentUri, umbracoSettings: umbracoSettings, urlProviders: new[] { - new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings: globalSettings.Object, snapshotService: snapshotService.Object); @@ -309,7 +309,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("http://example.com/test", 1111, umbracoSettings: umbracoSettings, urlProviders: new[] { - new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings: globalSettings.Object); Assert.AreEqual("/home/sub1/custom-sub-1/", umbracoContext.UrlProvider.GetUrl(1177)); @@ -328,7 +328,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("http://example.com/test", 1111, urlProviders: new[] { - new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings: globalSettings.Object); //mock the Umbraco settings that we need diff --git a/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs b/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs index 0a34fb8041..8fc099c90d 100644 --- a/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs @@ -183,7 +183,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings, urlProviders: new[] { - new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings:globalSettings.Object); SetDomains1(); @@ -210,13 +210,13 @@ namespace Umbraco.Tests.Routing public void Get_Url_SimpleWithSchemeAndPath(int nodeId, string currentUrl, bool absolute, string expected) { var settings = SettingsForTests.GenerateMockUmbracoSettings(); - + var globalSettings = Mock.Get(Factory.GetInstance()); //this will modify the IGlobalSettings instance stored in the container globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false); // ignored w/domains var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings, urlProviders: new[] { - new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings:globalSettings.Object); SetDomains2(); @@ -241,7 +241,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings, urlProviders: new[] { - new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings:globalSettings.Object); SetDomains3(); @@ -266,13 +266,13 @@ namespace Umbraco.Tests.Routing public void Get_Url_NestedDomains(int nodeId, string currentUrl, bool absolute, string expected) { var settings = SettingsForTests.GenerateMockUmbracoSettings(); - + var globalSettings = Mock.Get(Factory.GetInstance()); //this will modify the IGlobalSettings instance stored in the container globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false); // ignored w/domains var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings, urlProviders: new[] { - new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings:globalSettings.Object); SetDomains4(); @@ -287,13 +287,13 @@ namespace Umbraco.Tests.Routing public void Get_Url_DomainsAndCache() { var settings = SettingsForTests.GenerateMockUmbracoSettings(); - + var globalSettings = Mock.Get(Factory.GetInstance()); //this will modify the IGlobalSettings instance stored in the container globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false); // ignored w/domains var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings, urlProviders: new[] { - new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings:globalSettings.Object); SetDomains4(); @@ -350,13 +350,13 @@ namespace Umbraco.Tests.Routing public void Get_Url_Relative_Or_Absolute() { var settings = SettingsForTests.GenerateMockUmbracoSettings(); - + var globalSettings = Mock.Get(Factory.GetInstance()); //this will modify the IGlobalSettings instance stored in the container globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false); // ignored w/domains var umbracoContext = GetUmbracoContext("http://domain1.com/test", 1111, umbracoSettings: settings, urlProviders: new[] { - new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings:globalSettings.Object); SetDomains4(); @@ -380,7 +380,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("http://domain1.com/en/test", 1111, umbracoSettings: settings, urlProviders: new[] { - new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings:globalSettings.Object); SetDomains5(); diff --git a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs index 6587b2e4f6..c472e8d697 100644 --- a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs +++ b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs @@ -43,7 +43,7 @@ namespace Umbraco.Tests.Routing // get the nice url for 100111 var umbracoContext = GetUmbracoContext(url, 9999, umbracoSettings: settings, urlProviders: new [] { - new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper()) + new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper(), UriUtility) }, globalSettings:globalSettings.Object); Assert.AreEqual("http://domain2.com/1001-1-1/", umbracoContext.UrlProvider.GetUrl(100111, UrlMode.Absolute)); diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs index ed25764201..6af0c39ea5 100644 --- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs @@ -128,7 +128,8 @@ namespace Umbraco.Tests.Scoping Enumerable.Empty(), globalSettings, new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); if (setSingleton) Umbraco.Web.Composing.Current.UmbracoContextAccessor.UmbracoContext = umbracoContext; diff --git a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs index 7ff0776ba8..6511008dba 100644 --- a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs +++ b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs @@ -35,7 +35,7 @@ namespace Umbraco.Tests.Security Mock.Of(), new WebSecurity(Mock.Of(), Current.Services.UserService, globalSettings, IOHelper), TestObjects.GetUmbracoSettings(), new List(), Enumerable.Empty(), globalSettings, - new TestVariationContextAccessor(), IOHelper); + new TestVariationContextAccessor(), IOHelper, UriUtility); var runtime = Mock.Of(x => x.Level == RuntimeLevel.Install); var mgr = new BackOfficeCookieManager( @@ -55,7 +55,7 @@ namespace Umbraco.Tests.Security Mock.Of(), new WebSecurity(Mock.Of(), Current.Services.UserService, globalSettings, IOHelper), TestObjects.GetUmbracoSettings(), new List(), Enumerable.Empty(), globalSettings, - new TestVariationContextAccessor(), IOHelper); + new TestVariationContextAccessor(), IOHelper, UriUtility); var runtime = Mock.Of(x => x.Level == RuntimeLevel.Run); var mgr = new BackOfficeCookieManager(Mock.Of(accessor => accessor.UmbracoContext == umbCtx), runtime, TestObjects.GetGlobalSettings(), TestHelper.IOHelper); diff --git a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs index 9365c710b6..5892b3e59c 100644 --- a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs +++ b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs @@ -145,7 +145,8 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting Enumerable.Empty(), globalSettings, new TestVariationContextAccessor(), - TestHelper.IOHelper); + TestHelper.IOHelper, + TestHelper.UriUtility); //replace it umbracoContextAccessor.UmbracoContext = umbCtx; diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index a5ab3efe82..6fa20943cb 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -100,6 +100,8 @@ namespace Umbraco.Tests.TestHelpers public static IIOHelper IOHelper { get; } = new IOHelper(GetHostingEnvironment()); public static IMainDom MainDom { get; } = new MainDom(Mock.Of(), GetHostingEnvironment(), new MainDomSemaphoreLock(Mock.Of(), GetHostingEnvironment())); + public static UriUtility UriUtility { get; } = new UriUtility(GetHostingEnvironment()); + /// /// Maps the given making it rooted on . must start with ~/ /// diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs index 12282d1603..a969d3f8a4 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs @@ -137,7 +137,8 @@ namespace Umbraco.Tests.TestHelpers urlProviders, mediaUrlProviders, Mock.Of(), - TestHelper.IOHelper); + TestHelper.IOHelper, + TestHelper.UriUtility); return umbracoContextFactory.EnsureUmbracoContext(httpContext).UmbracoContext; } diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index 5f6467abc4..15863a0c23 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -391,7 +391,8 @@ namespace Umbraco.Tests.TestHelpers mediaUrlProviders ?? Enumerable.Empty(), globalSettings ?? Factory.GetInstance(), new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); if (setSingleton) Umbraco.Web.Composing.Current.UmbracoContextAccessor.UmbracoContext = umbracoContext; diff --git a/src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs b/src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs index f28613735d..1e742f2145 100644 --- a/src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs +++ b/src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs @@ -43,7 +43,8 @@ namespace Umbraco.Tests.Testing.Objects new UrlProviderCollection(new[] { urlProvider }), new MediaUrlProviderCollection(new[] { mediaUrlProvider }), Mock.Of(), - TestHelper.IOHelper); + TestHelper.IOHelper, + TestHelper.UriUtility); return umbracoContextFactory; } diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 4b21e11ff4..2e6f4c4c41 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -113,6 +113,7 @@ namespace Umbraco.Tests.Testing protected IJsonSerializer JsonNetSerializer { get; } = new JsonNetSerializer(); protected IIOHelper IOHelper { get; private set; } + protected UriUtility UriUtility => new UriUtility(HostingEnvironment); protected IDataTypeService DataTypeService => Factory.GetInstance(); protected IPasswordHasher PasswordHasher => Factory.GetInstance(); protected Lazy PropertyEditorCollection => new Lazy(() => Factory.GetInstance()); @@ -127,7 +128,7 @@ namespace Umbraco.Tests.Testing protected virtual IProfilingLogger ProfilingLogger => Factory.GetInstance(); - protected IHostingEnvironment HostingEnvironment => Factory.GetInstance(); + protected IHostingEnvironment HostingEnvironment { get; } = new AspNetHostingEnvironment(SettingsForTests.GetDefaultHostingSettings()); protected IIpResolver IpResolver => Factory.GetInstance(); protected IBackOfficeInfo BackOfficeInfo => Factory.GetInstance(); protected AppCaches AppCaches => Factory.GetInstance(); @@ -160,20 +161,18 @@ namespace Umbraco.Tests.Testing var proflogger = new ProfilingLogger(logger, profiler); IOHelper = TestHelper.IOHelper; - TypeFinder = new TypeFinder(logger); var appCaches = GetAppCaches(); var globalSettings = SettingsForTests.GetDefaultGlobalSettings(); - var hostingSettings = SettingsForTests.GetDefaultHostingSettings(); var settings = SettingsForTests.GetDefaultUmbracoSettings(); - IHostingEnvironment hostingEnvironment = new AspNetHostingEnvironment(hostingSettings); + IBackOfficeInfo backOfficeInfo = new AspNetBackOfficeInfo(globalSettings, IOHelper, settings, logger); IIpResolver ipResolver = new AspNetIpResolver(); UmbracoVersion = new UmbracoVersion(globalSettings); LocalizedTextService = new LocalizedTextService(new Dictionary>(), logger); - var typeLoader = GetTypeLoader(IOHelper, TypeFinder, appCaches.RuntimeCache, hostingEnvironment, proflogger, Options.TypeLoader); + var typeLoader = GetTypeLoader(IOHelper, TypeFinder, appCaches.RuntimeCache, HostingEnvironment, proflogger, Options.TypeLoader); var register = TestHelper.GetRegister(); @@ -184,6 +183,7 @@ namespace Umbraco.Tests.Testing Composition.RegisterUnique(IOHelper); + Composition.RegisterUnique(UriUtility); Composition.RegisterUnique(UmbracoVersion); Composition.RegisterUnique(TypeFinder); Composition.RegisterUnique(LocalizedTextService); @@ -192,7 +192,7 @@ namespace Umbraco.Tests.Testing Composition.RegisterUnique(profiler); Composition.RegisterUnique(proflogger); Composition.RegisterUnique(appCaches); - Composition.RegisterUnique(hostingEnvironment); + Composition.RegisterUnique(HostingEnvironment); Composition.RegisterUnique(backOfficeInfo); Composition.RegisterUnique(ipResolver); Composition.RegisterUnique(); @@ -498,7 +498,7 @@ namespace Umbraco.Tests.Testing Current.Reset(); // disposes the factory // reset all other static things that should not be static ;( - UriUtility.ResetAppDomainAppVirtualPath(); + UriUtility.ResetAppDomainAppVirtualPath(HostingEnvironment); SettingsForTests.Reset(); // FIXME: should it be optional? // clear static events diff --git a/src/Umbraco.Tests/Web/Mvc/RenderIndexActionSelectorAttributeTests.cs b/src/Umbraco.Tests/Web/Mvc/RenderIndexActionSelectorAttributeTests.cs index 2daa8e9a98..4c9e1250d4 100644 --- a/src/Umbraco.Tests/Web/Mvc/RenderIndexActionSelectorAttributeTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/RenderIndexActionSelectorAttributeTests.cs @@ -74,7 +74,8 @@ namespace Umbraco.Tests.Web.Mvc new UrlProviderCollection(Enumerable.Empty()), new MediaUrlProviderCollection(Enumerable.Empty()), Mock.Of(), - TestHelper.IOHelper); + TestHelper.IOHelper, + TestHelper.UriUtility); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()); var umbCtx = umbracoContextReference.UmbracoContext; @@ -105,7 +106,8 @@ namespace Umbraco.Tests.Web.Mvc new UrlProviderCollection(Enumerable.Empty()), new MediaUrlProviderCollection(Enumerable.Empty()), Mock.Of(), - TestHelper.IOHelper); + TestHelper.IOHelper, + TestHelper.UriUtility); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()); var umbCtx = umbracoContextReference.UmbracoContext; @@ -136,7 +138,8 @@ namespace Umbraco.Tests.Web.Mvc new UrlProviderCollection(Enumerable.Empty()), new MediaUrlProviderCollection(Enumerable.Empty()), Mock.Of(), - TestHelper.IOHelper); + TestHelper.IOHelper, + TestHelper.UriUtility); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()); var umbCtx = umbracoContextReference.UmbracoContext; @@ -167,7 +170,8 @@ namespace Umbraco.Tests.Web.Mvc new UrlProviderCollection(Enumerable.Empty()), new MediaUrlProviderCollection(Enumerable.Empty()), Mock.Of(), - TestHelper.IOHelper); + TestHelper.IOHelper, + TestHelper.UriUtility); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()); var umbCtx = umbracoContextReference.UmbracoContext; diff --git a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs index 6a75fe5457..4113284122 100644 --- a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs @@ -50,7 +50,8 @@ namespace Umbraco.Tests.Web.Mvc new UrlProviderCollection(Enumerable.Empty()), new MediaUrlProviderCollection(Enumerable.Empty()), Mock.Of(), - IOHelper); + IOHelper, + UriUtility); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()); var umbracoContext = umbracoContextReference.UmbracoContext; @@ -79,7 +80,8 @@ namespace Umbraco.Tests.Web.Mvc new UrlProviderCollection(Enumerable.Empty()), new MediaUrlProviderCollection(Enumerable.Empty()), Mock.Of(), - IOHelper); + IOHelper, + UriUtility); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()); var umbCtx = umbracoContextReference.UmbracoContext; @@ -111,7 +113,8 @@ namespace Umbraco.Tests.Web.Mvc new UrlProviderCollection(Enumerable.Empty()), new MediaUrlProviderCollection(Enumerable.Empty()), Mock.Of(), - IOHelper); + IOHelper, + UriUtility); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()); var umbracoContext = umbracoContextReference.UmbracoContext; @@ -150,7 +153,8 @@ namespace Umbraco.Tests.Web.Mvc new UrlProviderCollection(Enumerable.Empty()), new MediaUrlProviderCollection(Enumerable.Empty()), Mock.Of(), - IOHelper); + IOHelper, + UriUtility); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()); var umbracoContext = umbracoContextReference.UmbracoContext; diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs index 6fa54e34cb..851ccfd6c5 100644 --- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs @@ -446,7 +446,8 @@ namespace Umbraco.Tests.Web.Mvc Enumerable.Empty(), globalSettings, new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); //if (setSingleton) //{ diff --git a/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs b/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs index cb125fa851..759d522e27 100644 --- a/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs +++ b/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs @@ -35,7 +35,8 @@ namespace Umbraco.Tests.Web Enumerable.Empty(), TestObjects.GetGlobalSettings(), new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); var r1 = new RouteData(); r1.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbCtx); @@ -55,7 +56,8 @@ namespace Umbraco.Tests.Web Enumerable.Empty(), TestObjects.GetGlobalSettings(), new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); var r1 = new RouteData(); r1.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbCtx); @@ -85,7 +87,8 @@ namespace Umbraco.Tests.Web Enumerable.Empty(), TestObjects.GetGlobalSettings(), new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); var httpContext = Mock.Of(); diff --git a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs index ac0092ceb6..29c03f7cfa 100644 --- a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs +++ b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs @@ -8,7 +8,6 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Core.Strings; -using Umbraco.Web.Composing; using Umbraco.Web.Editors; using Umbraco.Web.Routing; @@ -17,7 +16,7 @@ namespace Umbraco.Web.Macros /// /// Legacy class used by macros which converts a published content item into a hashset of values /// - public class PublishedContentHashtableConverter + internal class PublishedContentHashtableConverter { #region Constructors diff --git a/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs index 40249a4750..dcd08750d3 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs @@ -31,6 +31,7 @@ namespace Umbraco.Web.Models.Mapping private readonly ILogger _logger; private readonly IUserService _userService; private readonly IVariationContextAccessor _variationContextAccessor; + private readonly UriUtility _uriUtility; private readonly TabsAndPropertiesMapper _tabsAndPropertiesMapper; private readonly ContentSavedStateMapper _stateMapper; private readonly ContentBasicSavedStateMapper _basicStateMapper; @@ -38,7 +39,7 @@ namespace Umbraco.Web.Models.Mapping public ContentMapDefinition(CommonMapper commonMapper, ICultureDictionary cultureDictionary, ILocalizedTextService localizedTextService, IContentService contentService, IContentTypeService contentTypeService, IFileService fileService, IUmbracoContextAccessor umbracoContextAccessor, IPublishedRouter publishedRouter, ILocalizationService localizationService, ILogger logger, - IUserService userService, IVariationContextAccessor variationContextAccessor, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider) + IUserService userService, IVariationContextAccessor variationContextAccessor, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, UriUtility uriUtility) { _commonMapper = commonMapper; _cultureDictionary = cultureDictionary; @@ -52,6 +53,7 @@ namespace Umbraco.Web.Models.Mapping _logger = logger; _userService = userService; _variationContextAccessor = variationContextAccessor; + _uriUtility = uriUtility; _tabsAndPropertiesMapper = new TabsAndPropertiesMapper(cultureDictionary, localizedTextService, contentTypeBaseServiceProvider); _stateMapper = new ContentSavedStateMapper(); @@ -177,7 +179,7 @@ namespace Umbraco.Web.Models.Mapping var urls = umbracoContext == null ? new[] { UrlInfo.Message("Cannot generate urls without a current Umbraco Context") } - : source.GetContentUrls(_publishedRouter, umbracoContext, _localizationService, _localizedTextService, _contentService, _variationContextAccessor, _logger).ToArray(); + : source.GetContentUrls(_publishedRouter, umbracoContext, _localizationService, _localizedTextService, _contentService, _variationContextAccessor, _logger, _uriUtility).ToArray(); return urls; } diff --git a/src/Umbraco.Web/Net/AspNetIpResolver.cs b/src/Umbraco.Web/Net/AspNetIpResolver.cs index 8cec45ff30..7eaca54663 100644 --- a/src/Umbraco.Web/Net/AspNetIpResolver.cs +++ b/src/Umbraco.Web/Net/AspNetIpResolver.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web { public string GetCurrentRequestIpAddress() { - var httpContext = HttpContext.Current == null ? (HttpContextBase) null : new HttpContextWrapper(HttpContext.Current); + var httpContext = HttpContext.Current is null ? null : new HttpContextWrapper(HttpContext.Current); var ip = httpContext.GetCurrentRequestIpAddress(); if (ip.ToLowerInvariant().StartsWith("unknown")) ip = ""; return ip; diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 9d026fb50a..e9e14894b0 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Web; using Examine; using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Models; using Umbraco.Core.Services; @@ -50,8 +51,8 @@ namespace Umbraco.Web Current.Configs.Settings().WebRouting.DisableAlternativeTemplates, Current.Configs.Settings().WebRouting.ValidateAlternativeTemplates, templateId); - } + public static bool IsAllowedTemplate(this IPublishedContent content, string templateAlias) { return content.IsAllowedTemplate( @@ -284,7 +285,7 @@ namespace Umbraco.Web { return parentNodes.DescendantsOrSelf(VariationContextAccessor, culture); } - + public static IEnumerable Descendants(this IPublishedContent content, string culture = null) { return content.Descendants(VariationContextAccessor, culture); @@ -700,38 +701,28 @@ namespace Umbraco.Web #region Url /// - /// Gets the url of the content item. - /// - /// - /// If the content item is a document, then this method returns the url of the - /// document. If it is a media, then this methods return the media url for the - /// 'umbracoFile' property. Use the MediaUrl() method to get the media url for other - /// properties. - /// The value of this property is contextual. It depends on the 'current' request uri, - /// if any. In addition, when the content type is multi-lingual, this is the url for the - /// specified culture. Otherwise, it is the invariant url. - /// - public static string Url(this IPublishedContent content, string culture = null, UrlMode mode = UrlMode.Default) - { - var umbracoContext = Composing.Current.UmbracoContext; + /// Gets the url of the content item. + /// + /// + /// If the content item is a document, then this method returns the url of the + /// document. If it is a media, then this methods return the media url for the + /// 'umbracoFile' property. Use the MediaUrl() method to get the media url for other + /// properties. + /// The value of this property is contextual. It depends on the 'current' request uri, + /// if any. In addition, when the content type is multi-lingual, this is the url for the + /// specified culture. Otherwise, it is the invariant url. + /// + public static string Url(this IPublishedContent content, string culture = null, UrlMode mode = UrlMode.Default) + { + var umbracoContext = Composing.Current.UmbracoContext; - if (umbracoContext == null) - throw new InvalidOperationException("Cannot resolve a Url when Current.UmbracoContext is null."); - if (umbracoContext.UrlProvider == null) - throw new InvalidOperationException("Cannot resolve a Url when Current.UmbracoContext.UrlProvider is null."); - switch (content.ContentType.ItemType) - { - case PublishedItemType.Content: - return umbracoContext.UrlProvider.GetUrl(content, mode, culture); + if (umbracoContext == null) + throw new InvalidOperationException("Cannot resolve a Url when Current.UmbracoContext is null."); - case PublishedItemType.Media: - return umbracoContext.UrlProvider.GetMediaUrl(content, mode, culture, Constants.Conventions.Media.File); + return content.Url(umbracoContext.UrlProvider, culture, mode); + } - default: - throw new NotSupportedException(); - } - } #endregion } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 392899a279..f2b380f95d 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -209,11 +209,6 @@ - - - - - @@ -354,13 +349,6 @@ - - - - - - - @@ -408,7 +396,6 @@ - @@ -499,7 +486,6 @@ - @@ -654,16 +640,9 @@ - - - - - - - @@ -685,24 +664,19 @@ - - - - Code - True True diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs index 8112b32263..87d3fbba4c 100644 --- a/src/Umbraco.Web/UmbracoContext.cs +++ b/src/Umbraco.Web/UmbracoContext.cs @@ -20,6 +20,7 @@ namespace Umbraco.Web { private readonly IGlobalSettings _globalSettings; private readonly IIOHelper _ioHelper; + private readonly UriUtility _uriUtility; private readonly Lazy _publishedSnapshot; private string _previewToken; private bool? _previewing; @@ -36,7 +37,8 @@ namespace Umbraco.Web IEnumerable mediaUrlProviders, IGlobalSettings globalSettings, IVariationContextAccessor variationContextAccessor, - IIOHelper ioHelper) + IIOHelper ioHelper, + UriUtility uriUtility) { if (httpContext == null) throw new ArgumentNullException(nameof(httpContext)); if (publishedSnapshotService == null) throw new ArgumentNullException(nameof(publishedSnapshotService)); @@ -47,6 +49,7 @@ namespace Umbraco.Web VariationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor)); _globalSettings = globalSettings ?? throw new ArgumentNullException(nameof(globalSettings)); _ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper)); + _uriUtility = uriUtility; // ensure that this instance is disposed when the request terminates, though we *also* ensure // this happens in the Umbraco module since the UmbracoCOntext is added to the HttpContext items. @@ -74,7 +77,7 @@ namespace Umbraco.Web // see: http://issues.umbraco.org/issue/U4-1890 // OriginalRequestUrl = GetRequestFromContext()?.Url ?? new Uri("http://localhost"); - CleanedUmbracoUrl = UriUtility.UriToUmbraco(OriginalRequestUrl); + CleanedUmbracoUrl = _uriUtility.UriToUmbraco(OriginalRequestUrl); UrlProvider = new UrlProvider(this, umbracoSettings.WebRouting, urlProviders, mediaUrlProviders, variationContextAccessor); } diff --git a/src/Umbraco.Web/UmbracoContextFactory.cs b/src/Umbraco.Web/UmbracoContextFactory.cs index 4c7ca2c2a3..27d8a12e02 100644 --- a/src/Umbraco.Web/UmbracoContextFactory.cs +++ b/src/Umbraco.Web/UmbracoContextFactory.cs @@ -34,11 +34,23 @@ namespace Umbraco.Web private readonly MediaUrlProviderCollection _mediaUrlProviders; private readonly IUserService _userService; private readonly IIOHelper _ioHelper; + private readonly UriUtility _uriUtility; /// /// Initializes a new instance of the class. /// - public UmbracoContextFactory(IUmbracoContextAccessor umbracoContextAccessor, IPublishedSnapshotService publishedSnapshotService, IVariationContextAccessor variationContextAccessor, IDefaultCultureAccessor defaultCultureAccessor, IUmbracoSettingsSection umbracoSettings, IGlobalSettings globalSettings, UrlProviderCollection urlProviders, MediaUrlProviderCollection mediaUrlProviders, IUserService userService, IIOHelper ioHelper) + public UmbracoContextFactory( + IUmbracoContextAccessor umbracoContextAccessor, + IPublishedSnapshotService publishedSnapshotService, + IVariationContextAccessor variationContextAccessor, + IDefaultCultureAccessor defaultCultureAccessor, + IUmbracoSettingsSection umbracoSettings, + IGlobalSettings globalSettings, + UrlProviderCollection urlProviders, + MediaUrlProviderCollection mediaUrlProviders, + IUserService userService, + IIOHelper ioHelper, + UriUtility uriUtility) { _umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor)); _publishedSnapshotService = publishedSnapshotService ?? throw new ArgumentNullException(nameof(publishedSnapshotService)); @@ -51,6 +63,7 @@ namespace Umbraco.Web _mediaUrlProviders = mediaUrlProviders ?? throw new ArgumentNullException(nameof(mediaUrlProviders)); _userService = userService ?? throw new ArgumentNullException(nameof(userService)); _ioHelper = ioHelper; + _uriUtility = uriUtility; } private IUmbracoContext CreateUmbracoContext(HttpContextBase httpContext) @@ -69,7 +82,7 @@ namespace Umbraco.Web var webSecurity = new WebSecurity(httpContext, _userService, _globalSettings, _ioHelper); - return new UmbracoContext(httpContext, _publishedSnapshotService, webSecurity, _umbracoSettings, _urlProviders, _mediaUrlProviders, _globalSettings, _variationContextAccessor, _ioHelper); + return new UmbracoContext(httpContext, _publishedSnapshotService, webSecurity, _umbracoSettings, _urlProviders, _mediaUrlProviders, _globalSettings, _variationContextAccessor, _ioHelper, _uriUtility); } /// diff --git a/src/Umbraco.Web/UmbracoInjectedModule.cs b/src/Umbraco.Web/UmbracoInjectedModule.cs index 72579188ed..de0102ed49 100644 --- a/src/Umbraco.Web/UmbracoInjectedModule.cs +++ b/src/Umbraco.Web/UmbracoInjectedModule.cs @@ -38,6 +38,7 @@ namespace Umbraco.Web private readonly IPublishedRouter _publishedRouter; private readonly IUmbracoContextFactory _umbracoContextFactory; private readonly RoutableDocumentFilter _routableDocumentLookup; + private readonly UriUtility _uriUtility; public UmbracoInjectedModule( IGlobalSettings globalSettings, @@ -45,7 +46,8 @@ namespace Umbraco.Web ILogger logger, IPublishedRouter publishedRouter, IUmbracoContextFactory umbracoContextFactory, - RoutableDocumentFilter routableDocumentLookup) + RoutableDocumentFilter routableDocumentLookup, + UriUtility uriUtility) { _globalSettings = globalSettings; _runtime = runtime; @@ -53,6 +55,7 @@ namespace Umbraco.Web _publishedRouter = publishedRouter; _umbracoContextFactory = umbracoContextFactory; _routableDocumentLookup = routableDocumentLookup; + _uriUtility = uriUtility; } #region HttpModule event handlers @@ -117,7 +120,7 @@ namespace Umbraco.Web var isRoutableAttempt = EnsureUmbracoRoutablePage(umbracoContext, httpContext); // raise event here - UmbracoModule.OnRouteAttempt(this, new RoutableAttemptEventArgs(isRoutableAttempt.Result, umbracoContext, httpContext)); + UmbracoModule.OnRouteAttempt(this, new RoutableAttemptEventArgs(isRoutableAttempt.Result, umbracoContext)); if (isRoutableAttempt.Success == false) return; httpContext.Trace.Write("UmbracoModule", "Umbraco request confirmed"); @@ -206,7 +209,7 @@ namespace Umbraco.Web case RuntimeLevel.Upgrade: // redirect to install ReportRuntime(level, "Umbraco must install or upgrade."); - var installPath = UriUtility.ToAbsolute(Constants.SystemDirectories.Install); + var installPath = _uriUtility.ToAbsolute(Constants.SystemDirectories.Install); var installUrl = $"{installPath}/?redir=true&url={HttpUtility.UrlEncode(uri.ToString())}"; httpContext.Response.Redirect(installUrl, true); return false; // cannot serve content @@ -238,7 +241,7 @@ namespace Umbraco.Web _logger.Warn("Umbraco has no content"); const string noContentUrl = "~/config/splashes/noNodes.aspx"; - httpContext.RewritePath(UriUtility.ToAbsolute(noContentUrl)); + httpContext.RewritePath(_uriUtility.ToAbsolute(noContentUrl)); return false; } @@ -426,7 +429,7 @@ namespace Umbraco.Web _logger.Verbose("End Request [{HttpRequestId}]: {RequestUrl} ({RequestDuration}ms)", httpRequestId, httpContext.Request.Url, DateTime.Now.Subtract(Current.UmbracoContext.ObjectCreated).TotalMilliseconds); } - UmbracoModule.OnEndRequest(this, new UmbracoRequestEventArgs(Current.UmbracoContext, new HttpContextWrapper(httpContext))); + UmbracoModule.OnEndRequest(this, new UmbracoRequestEventArgs(Current.UmbracoContext)); DisposeHttpContextItems(httpContext); };