diff --git a/src/Umbraco.Tests/Integration/GetCultureTests.cs b/src/Umbraco.Tests/Integration/GetCultureTests.cs
new file mode 100644
index 0000000000..977e0f313e
--- /dev/null
+++ b/src/Umbraco.Tests/Integration/GetCultureTests.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Moq;
+using NUnit.Framework;
+using umbraco.cms.businesslogic.web;
+using Umbraco.Core.Models;
+using Umbraco.Tests.Services;
+using Umbraco.Tests.TestHelpers;
+using Umbraco.Tests.TestHelpers.Entities;
+using Umbraco.Web.Routing;
+using Language = umbraco.cms.businesslogic.language.Language;
+
+namespace Umbraco.Tests.Integration
+{
+ [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)]
+ [TestFixture, RequiresSTA]
+ public class GetCultureTests : BaseServiceTest
+ {
+ protected override void FreezeResolution()
+ {
+ SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
+
+ base.FreezeResolution();
+ }
+
+ [Test]
+ public void GetCulture()
+ {
+ var contentTypeService = ServiceContext.ContentTypeService;
+ var contentType = MockedContentTypes.CreateSimpleContentType("umbBlah", "test Doc Type");
+ contentTypeService.Save(contentType);
+ var contentService = ServiceContext.ContentService;
+
+ var c1 = contentService.CreateContentWithIdentity("content", -1, "umbBlah");
+ var c2 = contentService.CreateContentWithIdentity("content", c1, "umbBlah");
+ var c3 = contentService.CreateContentWithIdentity("content", c1, "umbBlah");
+ var c4 = contentService.CreateContentWithIdentity("content", c3, "umbBlah");
+
+ foreach (var l in ServiceContext.LocalizationService.GetAllLanguages().Where(x => x.CultureName != "en-US").ToArray())
+ ServiceContext.LocalizationService.Delete(l);
+
+ var l0 = ServiceContext.LocalizationService.GetLanguageByIsoCode("en-US");
+ var l1 = new Core.Models.Language("fr-FR");
+ var l2 = new Core.Models.Language("de-DE");
+ ServiceContext.LocalizationService.Save(l1);
+ ServiceContext.LocalizationService.Save(l2);
+
+ foreach (var d in ServiceContext.DomainService.GetAll(true).ToArray())
+ ServiceContext.DomainService.Delete(d);
+
+ ServiceContext.DomainService.Save(new UmbracoDomain("domain1.com") {DomainName="domain1.com", RootContent = c1, Language = l0});
+ ServiceContext.DomainService.Save(new UmbracoDomain("domain1.fr") { DomainName = "domain1.fr", RootContent = c1, Language = l1 });
+ ServiceContext.DomainService.Save(new UmbracoDomain("*100112") { DomainName = "*100112", RootContent = c3, Language = l2 });
+
+ var content = c2;
+ var culture = Web.Models.ContentExtensions.GetCulture(null,
+ ServiceContext.DomainService, ServiceContext.LocalizationService, ServiceContext.ContentService,
+ content.Id, content.Path, new Uri("http://domain1.com/"));
+ Assert.AreEqual("en-US", culture.Name);
+
+ content = c2;
+ culture = Web.Models.ContentExtensions.GetCulture(null,
+ ServiceContext.DomainService, ServiceContext.LocalizationService, ServiceContext.ContentService,
+ content.Id, content.Path, new Uri("http://domain1.fr/"));
+ Assert.AreEqual("fr-FR", culture.Name);
+
+ content = c4;
+ culture = Web.Models.ContentExtensions.GetCulture(null,
+ ServiceContext.DomainService, ServiceContext.LocalizationService, ServiceContext.ContentService,
+ content.Id, content.Path, new Uri("http://domain1.fr/"));
+ Assert.AreEqual("de-DE", culture.Name);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
index 0cfd4a8b24..b6dfbd3584 100644
--- a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
+++ b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
@@ -13,31 +13,98 @@ using System.Configuration;
namespace Umbraco.Tests.Routing
{
[TestFixture]
- class DomainsAndCulturesTests : UrlRoutingTestBase
+ internal class DomainsAndCulturesTests : UrlRoutingTestBase
{
- void SetDomains1()
+ protected override void FreezeResolution()
+ {
+ SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
+
+ base.FreezeResolution();
+ }
+
+ private void SetDomains1()
{
SetupDomainServiceMock(new[]
{
- new UmbracoDomain("domain1.com/") {Id = 1, Language = new Language("de-DE"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}},
- new UmbracoDomain("domain1.com/en") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}},
- new UmbracoDomain("domain1.com/fr") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012}}
+ new UmbracoDomain("domain1.com/")
+ {
+ Id = 1,
+ Language = new Language("de-DE"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}
+ },
+ new UmbracoDomain("domain1.com/en")
+ {
+ Id = 1,
+ Language = new Language("en-US"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}
+ },
+ new UmbracoDomain("domain1.com/fr")
+ {
+ Id = 1,
+ Language = new Language("fr-FR"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012}
+ }
});
}
- void SetDomains2()
+ private void SetDomains2()
{
SetupDomainServiceMock(new[]
{
- new UmbracoDomain("domain1.com/") {Id = 1, Language = new Language("de-DE"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}},
- new UmbracoDomain("domain1.com/en") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}},
- new UmbracoDomain("domain1.com/fr") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012}},
- new UmbracoDomain("*1001") {Id = 1, Language = new Language("de-DE"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}},
- new UmbracoDomain("*10011") {Id = 1, Language = new Language("cs-CZ"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}},
- new UmbracoDomain("*100112") {Id = 1, Language = new Language("nl-NL"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 100112}},
- new UmbracoDomain("*1001122") {Id = 1, Language = new Language("da-DK"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001122}},
- new UmbracoDomain("*10012") {Id = 1, Language = new Language("nl-NL"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012}},
- new UmbracoDomain("*10031") {Id = 1, Language = new Language("nl-NL"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10031}}
+ new UmbracoDomain("domain1.com/")
+ {
+ Id = 1,
+ Language = new Language("de-DE"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}
+ },
+ new UmbracoDomain("domain1.com/en")
+ {
+ Id = 1,
+ Language = new Language("en-US"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}
+ },
+ new UmbracoDomain("domain1.com/fr")
+ {
+ Id = 1,
+ Language = new Language("fr-FR"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012}
+ },
+ new UmbracoDomain("*1001")
+ {
+ Id = 1,
+ Language = new Language("de-DE"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}
+ },
+ new UmbracoDomain("*10011")
+ {
+ Id = 1,
+ Language = new Language("cs-CZ"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}
+ },
+ new UmbracoDomain("*100112")
+ {
+ Id = 1,
+ Language = new Language("nl-NL"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 100112}
+ },
+ new UmbracoDomain("*1001122")
+ {
+ Id = 1,
+ Language = new Language("da-DK"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001122}
+ },
+ new UmbracoDomain("*10012")
+ {
+ Id = 1,
+ Language = new Language("nl-NL"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012}
+ },
+ new UmbracoDomain("*10031")
+ {
+ Id = 1,
+ Language = new Language("nl-NL"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10031}
+ }
});
}
@@ -49,82 +116,129 @@ namespace Umbraco.Tests.Routing
]>
-
+
-
+
This is some content]]>
-
+
-
+
-
+
-
+
-
+
This is some content]]>
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
This is some content]]>
-
+
-
+
-
+
-
+
-
+
This is some content]]>
-
+
-
+
-
+
-
+
-
+
";
@@ -144,7 +258,8 @@ namespace Umbraco.Tests.Routing
SetDomains1();
var routingContext = GetRoutingContext(inputUrl);
- var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
+ var url = routingContext.UmbracoContext.CleanedUmbracoUrl;
+ //very important to use the cleaned up umbraco url
var pcr = new PublishedContentRequest(url, routingContext);
// lookup domain
@@ -152,7 +267,7 @@ namespace Umbraco.Tests.Routing
Assert.AreEqual(expectedCulture, pcr.Culture.Name);
- SettingsForTests.HideTopLevelNodeFromPath = false;
+ SettingsForTests.HideTopLevelNodeFromPath = false;
var finder = new ContentFinderByNiceUrl();
var result = finder.TryFindContent(pcr);
@@ -191,7 +306,8 @@ namespace Umbraco.Tests.Routing
expectedCulture = expectedCulture ?? System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
var routingContext = GetRoutingContext(inputUrl);
- var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
+ var url = routingContext.UmbracoContext.CleanedUmbracoUrl;
+ //very important to use the cleaned up umbraco url
var pcr = new PublishedContentRequest(url, routingContext);
// lookup domain
@@ -209,5 +325,46 @@ namespace Umbraco.Tests.Routing
Assert.AreEqual(expectedCulture, pcr.Culture.Name);
Assert.AreEqual(pcr.PublishedContent.Id, expectedNode);
}
+
+ #region Cases
+ [TestCase(10011, "http://domain1.com/", "en-US")]
+ [TestCase(100111, "http://domain1.com/", "en-US")]
+ [TestCase(10011, "http://domain1.fr/", "fr-FR")]
+ [TestCase(100111, "http://domain1.fr/", "fr-FR")]
+ [TestCase(1001121, "http://domain1.fr/", "de-DE")]
+ #endregion
+ public void GetCulture(int nodeId, string currentUrl, string expectedCulture)
+ {
+ var domainService = SetupDomainServiceMock(new[]
+ {
+ new UmbracoDomain("domain1.com/")
+ {
+ Id = 1,
+ Language = new Language("en-US"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}
+ },
+ new UmbracoDomain("domain1.fr/")
+ {
+ Id = 1,
+ Language = new Language("fr-FR"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}
+ },
+ new UmbracoDomain("*100112")
+ {
+ Id = 1,
+ Language = new Language("de-DE"),
+ RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 100112}
+ }
+ });
+
+ var routingContext = GetRoutingContext("http://anything/");
+ var umbracoContext = routingContext.UmbracoContext;
+
+ var content = umbracoContext.ContentCache.GetById(nodeId);
+ Assert.IsNotNull(content);
+
+ var culture = Web.Models.ContentExtensions.GetCulture(umbracoContext, domainService, null, null, content.Id, content.Path, new Uri(currentUrl));
+ Assert.AreEqual(expectedCulture, culture.Name);
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs b/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs
index 295bb695e5..5802e023f0 100644
--- a/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs
+++ b/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs
@@ -21,7 +21,7 @@ namespace Umbraco.Tests.Routing
/// Sets up the mock domain service
///
///
- protected void SetupDomainServiceMock(IEnumerable allDomains)
+ protected IDomainService SetupDomainServiceMock(IEnumerable allDomains)
{
var domainService = Mock.Get(ServiceContext.DomainService);
//setup mock domain service
@@ -29,6 +29,7 @@ namespace Umbraco.Tests.Routing
.Returns((bool incWildcards) => incWildcards ? allDomains : allDomains.Where(d => d.IsWildcard == false));
domainService.Setup(service => service.GetAssignedDomains(It.IsAny(), It.IsAny()))
.Returns((int id, bool incWildcards) => allDomains.Where(d => d.RootContent.Id == id && (incWildcards || d.IsWildcard == false)));
+ return domainService.Object;
}
protected ServiceContext GetServiceContext(IUmbracoSettingsSection umbracoSettings, ILogger logger)
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index 43a81fb76a..0dce9281ef 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -174,6 +174,7 @@
+
diff --git a/src/Umbraco.Web/Models/ContentExtensions.cs b/src/Umbraco.Web/Models/ContentExtensions.cs
index 97aff5e2d3..977f8eaf0b 100644
--- a/src/Umbraco.Web/Models/ContentExtensions.cs
+++ b/src/Umbraco.Web/Models/ContentExtensions.cs
@@ -20,7 +20,9 @@ namespace Umbraco.Web.Models
public static CultureInfo GetCulture(this IContent content, Uri current = null)
{
return GetCulture(UmbracoContext.Current,
- ApplicationContext.Current.Services.DomainService, ApplicationContext.Current.Services.LocalizationService,
+ ApplicationContext.Current.Services.DomainService,
+ ApplicationContext.Current.Services.LocalizationService,
+ ApplicationContext.Current.Services.ContentService,
content.Id, content.Path,
current);
}
@@ -32,32 +34,64 @@ namespace Umbraco.Web.Models
/// An instance.
/// An implementation.
/// An implementation.
+ /// An implementation.
/// The content identifier.
/// The content path.
/// The request Uri.
/// The culture that would be selected to render the content.
- internal static CultureInfo GetCulture(UmbracoContext umbracoContext, IDomainService domainService, ILocalizationService localizationService,
+ internal static CultureInfo GetCulture(UmbracoContext umbracoContext,
+ IDomainService domainService, ILocalizationService localizationService, IContentService contentService,
int contentId, string contentPath, Uri current)
{
- var route = umbracoContext.ContentCache.GetRouteById(contentId); // cached
- var pos = route.IndexOf('/');
+ var route = umbracoContext == null
+ ? null // for tests only
+ : umbracoContext.ContentCache.GetRouteById(contentId); // cached
var domainHelper = new DomainHelper(domainService);
+ IDomain domain;
- var domain = pos == 0
- ? null
- : domainHelper.DomainForNode(int.Parse(route.Substring(0, pos)), current).UmbracoDomain;
+ if (route == null)
+ {
+ // if content is not published then route is null and we have to work
+ // on non-published content (note: could optimize by checking routes?)
+
+ var content = contentService.GetById(contentId);
+ if (content == null)
+ return GetDefaultCulture(localizationService);
+
+ var hasDomain = domainHelper.NodeHasDomains(content.Id);
+ while (hasDomain == false && content != null)
+ {
+ content = content.Parent();
+ hasDomain = content != null && domainHelper.NodeHasDomains(content.Id);
+ }
+
+ domain = hasDomain ? domainHelper.DomainForNode(content.Id, current).UmbracoDomain : null;
+ }
+ else
+ {
+ // if content is published then we have a (cached) route
+ // from which we can figure out the domain
+
+ var pos = route.IndexOf('/');
+ domain = pos == 0
+ ? null
+ : domainHelper.DomainForNode(int.Parse(route.Substring(0, pos)), current).UmbracoDomain;
+ }
if (domain == null)
- {
- var defaultLanguage = localizationService.GetAllLanguages().FirstOrDefault();
- return defaultLanguage == null ? CultureInfo.CurrentUICulture : new CultureInfo(defaultLanguage.IsoCode);
- }
+ return GetDefaultCulture(localizationService);
var wcDomain = DomainHelper.FindWildcardDomainInPath(domainService.GetAll(true), contentPath, domain.RootContent.Id);
return wcDomain == null
? new CultureInfo(domain.Language.IsoCode)
: new CultureInfo(wcDomain.Language.IsoCode);
}
+
+ private static CultureInfo GetDefaultCulture(ILocalizationService localizationService)
+ {
+ var defaultLanguage = localizationService.GetAllLanguages().FirstOrDefault();
+ return defaultLanguage == null ? CultureInfo.CurrentUICulture : new CultureInfo(defaultLanguage.IsoCode);
+ }
}
}
diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs
index 7302913d34..a735df88f9 100644
--- a/src/Umbraco.Web/PublishedContentExtensions.cs
+++ b/src/Umbraco.Web/PublishedContentExtensions.cs
@@ -1898,7 +1898,9 @@ namespace Umbraco.Web
public static CultureInfo GetCulture(this IPublishedContent content, Uri current = null)
{
return Models.ContentExtensions.GetCulture(UmbracoContext.Current,
- ApplicationContext.Current.Services.DomainService, ApplicationContext.Current.Services.LocalizationService,
+ ApplicationContext.Current.Services.DomainService,
+ ApplicationContext.Current.Services.LocalizationService,
+ ApplicationContext.Current.Services.ContentService,
content.Id, content.Path,
current);
}