diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedCultureInfos.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedCultureInfos.cs
index eedc97dbfc..d5096158a7 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedCultureInfos.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedCultureInfos.cs
@@ -13,10 +13,9 @@ namespace Umbraco.Core.Models.PublishedContent
///
public PublishedCultureInfo(string culture, string name, string urlSegment, DateTime date)
{
- if (string.IsNullOrWhiteSpace(culture)) throw new ArgumentNullOrEmptyException(nameof(culture));
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name));
- Culture = culture;
+ Culture = culture ?? throw new ArgumentNullException(nameof(culture));
Name = name;
UrlSegment = urlSegment;
Date = date;
diff --git a/src/Umbraco.Core/PublishedContentExtensions.cs b/src/Umbraco.Core/PublishedContentExtensions.cs
index a8cb0cdaf2..f220f307d6 100644
--- a/src/Umbraco.Core/PublishedContentExtensions.cs
+++ b/src/Umbraco.Core/PublishedContentExtensions.cs
@@ -37,7 +37,7 @@ namespace Umbraco.Core
culture = culture ?? Current.VariationContextAccessor.VariationContext?.Culture ?? "";
// either does not vary by culture, or has the specified culture
- return contents.Where(x => !ContentVariationExtensions.VariesByCulture((IPublishedContentType) x.ContentType) || HasCulture(x, culture));
+ return contents.Where(x => !x.ContentType.VariesByCulture() || HasCulture(x, culture));
}
///
@@ -49,7 +49,7 @@ namespace Umbraco.Core
{
// invariant has invariant value (whatever the requested culture)
if (!content.ContentType.VariesByCulture())
- return "NAME??"; // fixme where should the invariant one come from? should Cultures contain it?
+ return content.Cultures.TryGetValue("", out var invariantInfos) ? invariantInfos.Name : null;
// handle context culture for variant
if (culture == null)
@@ -69,7 +69,7 @@ namespace Umbraco.Core
{
// invariant has invariant value (whatever the requested culture)
if (!content.ContentType.VariesByCulture())
- return "URLSEGMENT??"; // fixme where should the invariant one come from? should Cultures contain it?
+ return content.Cultures.TryGetValue("", out var invariantInfos) ? invariantInfos.UrlSegment : null;
// handle context culture for variant
if (culture == null)
@@ -125,4 +125,4 @@ namespace Umbraco.Core
: children.Where(x => x.IsInvariantOrHasCulture(culture));
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedContentCache.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedContentCache.cs
index 8de0209c69..8ce6b10983 100644
--- a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedContentCache.cs
+++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedContentCache.cs
@@ -382,7 +382,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
return GetXml(preview).CreateNavigator().MoveToId(contentId.ToString(CultureInfo.InvariantCulture));
}
- public override IEnumerable GetAtRoot(bool preview)
+ public override IEnumerable GetAtRoot(bool preview, string culture = null)
{
return ConvertToDocuments(GetXml(preview).SelectNodes(XPathStrings.RootDocuments), preview);
}
diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedMediaCache.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedMediaCache.cs
index ba43921f1c..999d7f040d 100644
--- a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedMediaCache.cs
+++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedMediaCache.cs
@@ -105,7 +105,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
return GetUmbracoMedia(contentId) != null;
}
- public override IEnumerable GetAtRoot(bool preview)
+ public override IEnumerable GetAtRoot(bool preview, string culture = null)
{
var searchProvider = GetSearchProviderSafe();
diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedContent.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedContent.cs
index 4a60912757..3697863cb4 100644
--- a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedContent.cs
+++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedContent.cs
@@ -145,8 +145,15 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
}
}
- private static readonly Lazy> NoCultures = new Lazy>(() => new Dictionary());
- public override IReadOnlyDictionary Cultures => NoCultures.Value;
+ private Dictionary _cultures;
+
+ private Dictionary GetCultures()
+ {
+ EnsureNodeInitialized();
+ return new Dictionary { { "", new PublishedCultureInfo("", _name, _urlName, _updateDate) } };
+ }
+
+ public override IReadOnlyDictionary Cultures => _cultures ?? (_cultures = GetCultures());
public override string WriterName
{
diff --git a/src/Umbraco.Tests/Published/ConvertersTests.cs b/src/Umbraco.Tests/Published/ConvertersTests.cs
index 7ad81922e2..671129848c 100644
--- a/src/Umbraco.Tests/Published/ConvertersTests.cs
+++ b/src/Umbraco.Tests/Published/ConvertersTests.cs
@@ -4,16 +4,14 @@ using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
-using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
-using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Tests.Components;
+using Umbraco.Tests.PublishedContent;
using Umbraco.Tests.TestHelpers;
-using Umbraco.Tests.TestHelpers.Stubs;
using Umbraco.Web;
using Umbraco.Web.PublishedCache;
@@ -127,7 +125,7 @@ namespace Umbraco.Tests.Published
var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false);
var cntType1 = contentTypeFactory.CreateContentType(1001, "cnt1", t => Enumerable.Empty());
- var cnt1 = new TestPublishedContent(cntType1, 1234, Guid.NewGuid(), new Dictionary(), false);
+ var cnt1 = new SolidPublishedContent(cntType1) { Id = 1234 };
cacheContent[cnt1.Id] = cnt1;
Assert.AreSame(cnt1, element1.Value("prop1"));
@@ -224,8 +222,16 @@ namespace Umbraco.Tests.Published
var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "val1" } }, false);
var element2 = new PublishedElement(elementType2, Guid.NewGuid(), new Dictionary { { "prop2", "1003" } }, false);
- var cnt1 = new TestPublishedContent(contentType1, 1003, Guid.NewGuid(), new Dictionary { { "prop1", "val1" } }, false);
- var cnt2 = new TestPublishedContent(contentType2, 1004, Guid.NewGuid(), new Dictionary { { "prop2", "1003" } }, false);
+ var cnt1 = new SolidPublishedContent(contentType1)
+ {
+ Id = 1003,
+ Properties = new[] { new SolidPublishedProperty { Alias = "prop1", SolidHasValue = true, SolidValue = "val1" } }
+ };
+ var cnt2 = new SolidPublishedContent(contentType1)
+ {
+ Id = 1004,
+ Properties = new[] { new SolidPublishedProperty { Alias = "prop2", SolidHasValue = true, SolidValue = "1003" } }
+ };
cacheContent[cnt1.Id] = cnt1.CreateModel();
cacheContent[cnt2.Id] = cnt2.CreateModel();
diff --git a/src/Umbraco.Tests/Published/NestedContentTests.cs b/src/Umbraco.Tests/Published/NestedContentTests.cs
index 432247b09f..9385b8955a 100644
--- a/src/Umbraco.Tests/Published/NestedContentTests.cs
+++ b/src/Umbraco.Tests/Published/NestedContentTests.cs
@@ -11,6 +11,7 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
+using Umbraco.Tests.PublishedContent;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Models;
@@ -167,12 +168,16 @@ namespace Umbraco.Tests.Published
var key = Guid.NewGuid();
var keyA = Guid.NewGuid();
- var content = new TestPublishedContent(contentType1, key, new[]
+ var content = new SolidPublishedContent(contentType1)
{
- new TestPublishedProperty(contentType1.GetPropertyType("property1"), $@"[
+ Key = key,
+ Properties = new []
+ {
+ new TestPublishedProperty(contentType1.GetPropertyType("property1"), $@"[
{{ ""key"": ""{keyA}"", ""propertyN1"": ""foo"", ""ncContentTypeAlias"": ""contentN1"" }}
]")
- });
+ }
+ };
var value = content.Value("property1");
// nested single converter returns proper TestModel value
@@ -194,13 +199,17 @@ namespace Umbraco.Tests.Published
var key = Guid.NewGuid();
var keyA = Guid.NewGuid();
var keyB = Guid.NewGuid();
- var content = new TestPublishedContent(contentType2, key, new[]
+ var content = new SolidPublishedContent(contentType2)
{
- new TestPublishedProperty(contentType2.GetPropertyType("property2"), $@"[
+ Key = key,
+ Properties = new[]
+ {
+ new TestPublishedProperty(contentType2.GetPropertyType("property2"), $@"[
{{ ""key"": ""{keyA}"", ""propertyN1"": ""foo"", ""ncContentTypeAlias"": ""contentN1"" }},
{{ ""key"": ""{keyB}"", ""propertyN1"": ""bar"", ""ncContentTypeAlias"": ""contentN1"" }}
]")
- });
+ }
+ };
var value = content.Value("property2");
// nested many converter returns proper IEnumerable value
@@ -257,52 +266,5 @@ namespace Umbraco.Tests.Published
public override object GetValue(string culture = null, string segment = null) => PropertyType.ConvertInterToObject(_owner, ReferenceCacheLevel, InterValue, _preview);
public override object GetXPathValue(string culture = null, string segment = null) => throw new WontImplementException();
}
-
- class TestPublishedContent : PublishedContentBase
- {
- public TestPublishedContent(IPublishedContentType contentType, Guid key, IEnumerable properties)
- {
- ContentType = contentType;
- Key = key;
- var propertiesA = properties.ToArray();
- Properties = propertiesA;
- foreach (var property in propertiesA)
- property.SetOwner(this);
- }
-
- // ReSharper disable UnassignedGetOnlyAutoProperty
- public override PublishedItemType ItemType { get; }
- public override bool IsDraft(string culture = null) => false;
- public override bool IsPublished(string culture = null) => true;
- public override IPublishedContent Parent { get; }
- public override IEnumerable Children { get; }
- public override IEnumerable ChildrenForAllCultures => Children;
- public override IPublishedContentType ContentType { get; }
- // ReSharper restore UnassignedGetOnlyAutoProperty
-
- // ReSharper disable UnassignedGetOnlyAutoProperty
- public override int Id { get; }
- public override int? TemplateId { get; }
- public override int SortOrder { get; }
- public override string Name { get; }
- public override IReadOnlyDictionary Cultures => throw new NotSupportedException();
- public override string UrlSegment { get; }
- public override string WriterName { get; }
- public override string CreatorName { get; }
- public override int WriterId { get; }
- public override int CreatorId { get; }
- public override string Path { get; }
- public override DateTime CreateDate { get; }
- public override DateTime UpdateDate { get; }
- public override int Level { get; }
- public override Guid Key { get; }
- // ReSharper restore UnassignedGetOnlyAutoProperty
-
- public override IEnumerable Properties { get; }
- public override IPublishedProperty GetProperty(string alias)
- {
- return Properties.FirstOrDefault(x => x.Alias.InvariantEquals(alias));
- }
- }
}
}
diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs
index d77d1e4701..7e8a4b18e1 100644
--- a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs
@@ -20,6 +20,7 @@ using Umbraco.Core.Strings;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing.Objects;
using Umbraco.Tests.Testing.Objects.Accessors;
+using Umbraco.Web;
using Umbraco.Web.Cache;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.PublishedCache.NuCache;
@@ -33,20 +34,25 @@ namespace Umbraco.Tests.PublishedContent
private IPublishedSnapshotService _snapshotService;
private IVariationContextAccessor _variationAccesor;
private IPublishedSnapshotAccessor _snapshotAccessor;
- private ContentType _contentType;
- private PropertyType _propertyType;
+ private ContentType _contentTypeInvariant;
+ private ContentType _contentTypeVariant;
private TestDataSource _source;
private void Init(IEnumerable kits)
{
Current.Reset();
- Current.UnlockConfigs();
- Current.Configs.Add(SettingsForTests.GenerateMockUmbracoSettings);
- Current.Configs.Add(() => new GlobalSettings());
- var globalSettings = Current.Configs.Global();
- // create a data source for NuCache
- _source = new TestDataSource(kits);
+ var factory = Mock.Of();
+ Current.Factory = factory;
+
+ var configs = new Configs();
+ Mock.Get(factory).Setup(x => x.GetInstance(typeof(Configs))).Returns(configs);
+ var globalSettings = new GlobalSettings();
+ configs.Add(SettingsForTests.GenerateMockUmbracoSettings);
+ configs.Add(() => globalSettings);
+
+ var publishedModelFactory = new NoopPublishedModelFactory();
+ Mock.Get(factory).Setup(x => x.GetInstance(typeof(IPublishedModelFactory))).Returns(publishedModelFactory);
var runtime = Mock.Of();
Mock.Get(runtime).Setup(x => x.Level).Returns(RuntimeLevel.Run);
@@ -59,13 +65,18 @@ namespace Umbraco.Tests.PublishedContent
dataType
};
- _propertyType = new PropertyType("Umbraco.Void.Editor", ValueStorageType.Nvarchar) { Alias = "prop", DataTypeId = 3, Variations = ContentVariation.Nothing };
- _contentType = new ContentType(-1) { Id = 2, Alias = "ctype", Variations = ContentVariation.Nothing };
- _contentType.AddPropertyType(_propertyType);
+ var propertyType = new PropertyType("Umbraco.Void.Editor", ValueStorageType.Nvarchar) { Alias = "prop", DataTypeId = 3, Variations = ContentVariation.Nothing };
+ _contentTypeInvariant = new ContentType(-1) { Id = 2, Alias = "itype", Variations = ContentVariation.Nothing };
+ _contentTypeInvariant.AddPropertyType(propertyType);
+
+ propertyType = new PropertyType("Umbraco.Void.Editor", ValueStorageType.Nvarchar) { Alias = "prop", DataTypeId = 3, Variations = ContentVariation.Culture };
+ _contentTypeVariant = new ContentType(-1) { Id = 3, Alias = "vtype", Variations = ContentVariation.Culture };
+ _contentTypeVariant.AddPropertyType(propertyType);
var contentTypes = new[]
{
- _contentType
+ _contentTypeInvariant,
+ _contentTypeVariant
};
var contentTypeService = Mock.Of();
@@ -109,6 +120,9 @@ namespace Umbraco.Tests.PublishedContent
_variationAccesor = new TestVariationContextAccessor();
_snapshotAccessor = new TestPublishedSnapshotAccessor();
+ // create a data source for NuCache
+ _source = new TestDataSource(kits);
+
// at last, create the complete NuCache snapshot service!
var options = new PublishedSnapshotService.Options { IgnoreLocalDb = true };
_snapshotService = new PublishedSnapshotService(options,
@@ -133,9 +147,11 @@ namespace Umbraco.Tests.PublishedContent
// invariant is the current default
_variationAccesor.VariationContext = new VariationContext();
+
+ Mock.Get(factory).Setup(x => x.GetInstance(typeof(IVariationContextAccessor))).Returns(_variationAccesor);
}
- private IEnumerable GetKits()
+ private IEnumerable GetInvariantKits()
{
var paths = new Dictionary { { -1, "-1" } };
@@ -146,10 +162,11 @@ namespace Umbraco.Tests.PublishedContent
var path = paths[id] = parentPath + "," + id;
var level = path.Count(x => x == ',');
+ var now = DateTime.Now;
return new ContentNodeKit
{
- ContentTypeId = 2,
+ ContentTypeId = _contentTypeInvariant.Id,
Node = new ContentNode(id, Guid.NewGuid(), level, path, sortOrder, parentId, DateTime.Now, 0),
DraftData = null,
PublishedData = new ContentData
@@ -158,7 +175,7 @@ namespace Umbraco.Tests.PublishedContent
Published = true,
TemplateId = 0,
VersionId = 1,
- VersionDate = DateTime.Now,
+ VersionDate = now,
WriterId = 0,
Properties = new Dictionary(),
CultureInfos = new Dictionary()
@@ -184,6 +201,69 @@ namespace Umbraco.Tests.PublishedContent
yield return CreateKit(12, 4, 2);
}
+ private IEnumerable GetVariantKits()
+ {
+ var paths = new Dictionary { { -1, "-1" } };
+
+ Dictionary GetCultureInfos(int id, DateTime now)
+ {
+ var en = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
+ var fr = new[] { 1, 3, 4, 6, 7, 9, 10, 12 };
+
+ var infos = new Dictionary();
+ if (en.Contains(id))
+ infos["en-US"] = new CultureVariation { Name = "N" + id + "-" + "en-US", Date = now, IsDraft = false };
+ if (fr.Contains(id))
+ infos["fr-FR"] = new CultureVariation { Name = "N" + id + "-" + "fr-FR", Date = now, IsDraft = false };
+ return infos;
+ }
+
+ ContentNodeKit CreateKit(int id, int parentId, int sortOrder)
+ {
+ if (!paths.TryGetValue(parentId, out var parentPath))
+ throw new Exception("Unknown parent.");
+
+ var path = paths[id] = parentPath + "," + id;
+ var level = path.Count(x => x == ',');
+ var now = DateTime.Now;
+
+ return new ContentNodeKit
+ {
+ ContentTypeId = _contentTypeVariant.Id,
+ Node = new ContentNode(id, Guid.NewGuid(), level, path, sortOrder, parentId, DateTime.Now, 0),
+ DraftData = null,
+ PublishedData = new ContentData
+ {
+ Name = "N" + id,
+ Published = true,
+ TemplateId = 0,
+ VersionId = 1,
+ VersionDate = now,
+ WriterId = 0,
+ Properties = new Dictionary(),
+ CultureInfos = GetCultureInfos(id, now)
+ }
+ };
+ }
+
+ yield return CreateKit(1, -1, 1);
+ yield return CreateKit(2, -1, 2);
+ yield return CreateKit(3, -1, 3);
+
+ yield return CreateKit(4, 1, 1);
+ yield return CreateKit(5, 1, 2);
+ yield return CreateKit(6, 1, 3);
+
+ yield return CreateKit(7, 2, 3);
+ yield return CreateKit(8, 2, 2);
+ yield return CreateKit(9, 2, 1);
+
+ yield return CreateKit(10, 3, 1);
+
+ yield return CreateKit(11, 4, 1);
+ yield return CreateKit(12, 4, 2);
+ }
+
[Test]
public void EmptyTest()
{
@@ -199,7 +279,7 @@ namespace Umbraco.Tests.PublishedContent
[Test]
public void ChildrenTest()
{
- Init(GetKits());
+ Init(GetInvariantKits());
var snapshot = _snapshotService.CreatePublishedSnapshot(previewToken: null);
_snapshotAccessor.PublishedSnapshot = snapshot;
@@ -226,7 +306,7 @@ namespace Umbraco.Tests.PublishedContent
[Test]
public void ParentTest()
{
- Init(GetKits());
+ Init(GetInvariantKits());
var snapshot = _snapshotService.CreatePublishedSnapshot(previewToken: null);
_snapshotAccessor.PublishedSnapshot = snapshot;
@@ -252,7 +332,7 @@ namespace Umbraco.Tests.PublishedContent
[Test]
public void MoveToRootTest()
{
- Init(GetKits());
+ Init(GetInvariantKits());
// get snapshot
var snapshot = _snapshotService.CreatePublishedSnapshot(previewToken: null);
@@ -294,7 +374,7 @@ namespace Umbraco.Tests.PublishedContent
[Test]
public void MoveFromRootTest()
{
- Init(GetKits());
+ Init(GetInvariantKits());
// get snapshot
var snapshot = _snapshotService.CreatePublishedSnapshot(previewToken: null);
@@ -336,7 +416,7 @@ namespace Umbraco.Tests.PublishedContent
[Test]
public void ReOrderTest()
{
- Init(GetKits());
+ Init(GetInvariantKits());
// get snapshot
var snapshot = _snapshotService.CreatePublishedSnapshot(previewToken: null);
@@ -411,7 +491,7 @@ namespace Umbraco.Tests.PublishedContent
[Test]
public void MoveTest()
{
- Init(GetKits());
+ Init(GetInvariantKits());
// get snapshot
var snapshot = _snapshotService.CreatePublishedSnapshot(previewToken: null);
@@ -512,11 +592,90 @@ namespace Umbraco.Tests.PublishedContent
Assert.AreEqual(1, snapshot.Content.GetById(7).Parent?.Id);
}
+ [Test]
+ public void VariantChildrenTest()
+ {
+ Init(GetVariantKits());
+
+ var snapshot = _snapshotService.CreatePublishedSnapshot(previewToken: null);
+ _snapshotAccessor.PublishedSnapshot = snapshot;
+
+ _variationAccesor.VariationContext = new VariationContext("en-US");
+
+ var documents = snapshot.Content.GetAtRoot().ToArray();
+ AssertDocuments(documents, "N1-en-US", "N2-en-US", "N3-en-US");
+
+ documents = snapshot.Content.GetById(1).Children().ToArray();
+ AssertDocuments(documents, "N4-en-US", "N5-en-US", "N6-en-US");
+
+ documents = snapshot.Content.GetById(2).Children().ToArray();
+ AssertDocuments(documents, "N9-en-US", "N8-en-US", "N7-en-US");
+
+ documents = snapshot.Content.GetById(3).Children().ToArray();
+ AssertDocuments(documents, "N10-en-US");
+
+ documents = snapshot.Content.GetById(4).Children().ToArray();
+ AssertDocuments(documents, "N11-en-US", "N12-en-US");
+
+ documents = snapshot.Content.GetById(10).Children().ToArray();
+ AssertDocuments(documents);
+
+
+ _variationAccesor.VariationContext = new VariationContext("fr-FR");
+
+ documents = snapshot.Content.GetAtRoot().ToArray();
+ AssertDocuments(documents, "N1-fr-FR", "N3-fr-FR");
+
+ documents = snapshot.Content.GetById(1).Children().ToArray();
+ AssertDocuments(documents, "N4-fr-FR", "N6-fr-FR");
+
+ documents = snapshot.Content.GetById(2).Children().ToArray();
+ AssertDocuments(documents, "N9-fr-FR", "N7-fr-FR");
+
+ documents = snapshot.Content.GetById(3).Children().ToArray();
+ AssertDocuments(documents, "N10-fr-FR");
+
+ documents = snapshot.Content.GetById(4).Children().ToArray();
+ AssertDocuments(documents, "N12-fr-FR");
+
+ documents = snapshot.Content.GetById(10).Children().ToArray();
+ AssertDocuments(documents);
+
+ documents = snapshot.Content.GetById(1).Children("*").ToArray();
+ AssertDocuments(documents, "N4-fr-FR", null, "N6-fr-FR");
+ AssertDocuments("en-US", documents, "N4-en-US", "N5-en-US", "N6-en-US");
+
+ documents = snapshot.Content.GetById(1).Children("en-US").ToArray();
+ AssertDocuments(documents, "N4-fr-FR", null, "N6-fr-FR");
+ AssertDocuments("en-US", documents, "N4-en-US", "N5-en-US", "N6-en-US");
+
+ documents = snapshot.Content.GetById(1).ChildrenForAllCultures.ToArray();
+ AssertDocuments(documents, "N4-fr-FR", null, "N6-fr-FR");
+ AssertDocuments("en-US", documents, "N4-en-US", "N5-en-US", "N6-en-US");
+
+
+ documents = snapshot.Content.GetAtRoot("*").ToArray();
+ AssertDocuments(documents, "N1-fr-FR", null, "N3-fr-FR");
+
+ documents = snapshot.Content.GetById(1).DescendantsOrSelf().ToArray();
+ AssertDocuments(documents, "N1-fr-FR", "N4-fr-FR", "N12-fr-FR", "N6-fr-FR");
+
+ documents = snapshot.Content.GetById(1).DescendantsOrSelf("*").ToArray();
+ AssertDocuments(documents, "N1-fr-FR", "N4-fr-FR", null /*11*/, "N12-fr-FR", null /*5*/, "N6-fr-FR");
+ }
+
private void AssertDocuments(IPublishedContent[] documents, params string[] names)
{
Assert.AreEqual(names.Length, documents.Length);
for (var i = 0; i < names.Length; i++)
- Assert.AreEqual(names[i], documents[i].Name());
+ Assert.AreEqual(names[i], documents[i].Name);
+ }
+
+ private void AssertDocuments(string culture, IPublishedContent[] documents, params string[] names)
+ {
+ Assert.AreEqual(names.Length, documents.Length);
+ for (var i = 0; i < names.Length; i++)
+ Assert.AreEqual(names[i], documents[i].Name(culture));
}
}
}
diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs
index dc035c1645..b66404c954 100644
--- a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs
@@ -38,10 +38,18 @@ namespace Umbraco.Tests.PublishedContent
private void Init()
{
Current.Reset();
- Current.UnlockConfigs();
- Current.Configs.Add(SettingsForTests.GenerateMockUmbracoSettings);
- Current.Configs.Add(() => new GlobalSettings());
- var globalSettings = Current.Configs.Global();
+
+ var factory = Mock.Of();
+ Current.Factory = factory;
+
+ var configs = new Configs();
+ Mock.Get(factory).Setup(x => x.GetInstance(typeof(Configs))).Returns(configs);
+ var globalSettings = new GlobalSettings();
+ configs.Add(SettingsForTests.GenerateMockUmbracoSettings);
+ configs.Add(() => globalSettings);
+
+ var publishedModelFactory = new NoopPublishedModelFactory();
+ Mock.Get(factory).Setup(x => x.GetInstance(typeof(IPublishedModelFactory))).Returns(publishedModelFactory);
// create a content node kit
var kit = new ContentNodeKit
@@ -184,6 +192,8 @@ namespace Umbraco.Tests.PublishedContent
// invariant is the current default
_variationAccesor.VariationContext = new VariationContext();
+
+ Mock.Get(factory).Setup(x => x.GetInstance(typeof(IVariationContextAccessor))).Returns(_variationAccesor);
}
[Test]
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
index 5c22295547..cc455b8e5d 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
@@ -97,7 +97,7 @@ namespace Umbraco.Tests.PublishedContent
{
var doc = GetContent(true, 1);
//change a doc type alias
- var c = (TestPublishedContent)doc.Children.ElementAt(0);
+ var c = (SolidPublishedContent)doc.Children.ElementAt(0);
c.ContentType = new PublishedContentType(22, "DontMatch", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
var dt = doc.ChildrenAsTable(Current.Services, "Child");
@@ -129,7 +129,8 @@ namespace Umbraco.Tests.PublishedContent
var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService);
var contentTypeAlias = createChildren ? "Parent" : "Child";
- var d = new TestPublishedContent
+ var contentType = new PublishedContentType(22, contentTypeAlias, PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
+ var d = new SolidPublishedContent(contentType)
{
CreateDate = DateTime.Now,
CreatorId = 1,
@@ -140,7 +141,7 @@ namespace Umbraco.Tests.PublishedContent
UpdateDate = DateTime.Now,
Path = "-1,3",
UrlSegment = "home-page",
- Name = "Page" + Guid.NewGuid().ToString(),
+ Name = "Page" + Guid.NewGuid(),
Version = Guid.NewGuid(),
WriterId = 1,
WriterName = "Shannon",
@@ -175,62 +176,7 @@ namespace Umbraco.Tests.PublishedContent
new RawValueProperty(factory.CreatePropertyType("property3", 1), d, "value" + (indexVals + 2)));
}
- d.ContentType = new PublishedContentType(22, contentTypeAlias, PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
return d;
}
-
- // note - could probably rewrite those tests using SolidPublishedContentCache
- // l8tr...
- private class TestPublishedContent : IPublishedContent
- {
- public string Url { get; set; }
- public PublishedItemType ItemType { get; set; }
- public IPublishedContent Parent { get; set; }
- public int Id { get; set; }
- public Guid Key { get; set; }
- public int? TemplateId { get; set; }
- public int SortOrder { get; set; }
- public string Name { get; set; }
- public IReadOnlyDictionary Cultures => throw new NotSupportedException();
- public string UrlSegment { get; set; }
- public string WriterName { get; set; }
- public string CreatorName { get; set; }
- public int WriterId { get; set; }
- public int CreatorId { get; set; }
- public string Path { get; set; }
- public DateTime CreateDate { get; set; }
- public DateTime UpdateDate { get; set; }
- public Guid Version { get; set; }
- public int Level { get; set; }
- public bool IsDraft(string culture = null) => false;
- public bool IsPublished(string culture = null) => true;
-
- public IEnumerable Properties { get; set; }
-
- public IEnumerable Children { get; set; }
- public IEnumerable ChildrenForAllCultures => Children;
-
- public IPublishedProperty GetProperty(string alias)
- {
- return Properties.FirstOrDefault(x => x.Alias.InvariantEquals(alias));
- }
-
- public IPublishedProperty GetProperty(string alias, bool recurse)
- {
- var property = GetProperty(alias);
- if (recurse == false) return property;
-
- IPublishedContent content = this;
- while (content != null && (property == null || property.HasValue() == false))
- {
- content = content.Parent;
- property = content == null ? null : content.GetProperty(alias);
- }
-
- return property;
- }
-
- public IPublishedContentType ContentType { get; set; }
- }
}
}
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index fd0837b0ab..f54971a197 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -821,7 +821,7 @@ namespace Umbraco.Tests.PublishedContent
var level1_2 = GetNode(1175);
var level1_3 = GetNode(4444);
- _publishedSnapshotAccessorMock.Setup(x => x.PublishedSnapshot.Content.GetAtRoot()).Returns(new []{root});
+ _publishedSnapshotAccessorMock.Setup(x => x.PublishedSnapshot.Content.GetAtRoot(It.IsAny())).Returns(new []{root});
CollectionAssertAreEqual(new []{root}, root.SiblingsAndSelf());
@@ -860,7 +860,7 @@ namespace Umbraco.Tests.PublishedContent
var level1_2 = GetNode(1175);
var level1_3 = GetNode(4444);
- _publishedSnapshotAccessorMock.Setup(x => x.PublishedSnapshot.Content.GetAtRoot()).Returns(new []{root});
+ _publishedSnapshotAccessorMock.Setup(x => x.PublishedSnapshot.Content.GetAtRoot(It.IsAny())).Returns(new []{root});
CollectionAssertAreEqual(new IPublishedContent[0], root.Siblings());
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs
index b789eb0ef8..f801d02c5b 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs
@@ -495,7 +495,7 @@ namespace Umbraco.Tests.PublishedContent
Assert.AreEqual(nodeId, converted.Id);
Assert.AreEqual(3, converted.Level);
Assert.AreEqual(1, converted.SortOrder);
- Assert.AreEqual("Sam's Umbraco Image", converted.Name());
+ Assert.AreEqual("Sam's Umbraco Image", converted.Name);
Assert.AreEqual("-1,1111,2222,2112", converted.Path);
}
diff --git a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
index ab5a65146a..860b9b9179 100644
--- a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
+++ b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
@@ -100,7 +100,7 @@ namespace Umbraco.Tests.PublishedContent
return _content.ContainsKey(contentId);
}
- public override IEnumerable GetAtRoot(bool preview)
+ public override IEnumerable GetAtRoot(bool preview, string culture = null)
{
return _content.Values.Where(x => x.Parent == null);
}
@@ -176,13 +176,19 @@ namespace Umbraco.Tests.PublishedContent
#region Content
+ private Dictionary _cultures;
+
+ private Dictionary GetCultures()
+ {
+ return new Dictionary { { "", new PublishedCultureInfo("", Name, UrlSegment, UpdateDate) } };
+ }
+
public int Id { get; set; }
public Guid Key { get; set; }
public int? TemplateId { get; set; }
public int SortOrder { get; set; }
public string Name { get; set; }
- public PublishedCultureInfo GetCulture(string culture = null) => throw new NotSupportedException();
- public IReadOnlyDictionary Cultures => throw new NotSupportedException();
+ public IReadOnlyDictionary Cultures => _cultures ?? (_cultures = GetCultures());
public string UrlSegment { get; set; }
public string WriterName { get; set; }
public string CreatorName { get; set; }
@@ -195,7 +201,7 @@ namespace Umbraco.Tests.PublishedContent
public int Level { get; set; }
public string Url { get; set; }
- public PublishedItemType ItemType { get { return PublishedItemType.Content; } }
+ public PublishedItemType ItemType => PublishedItemType.Content;
public bool IsDraft(string culture = null) => false;
public bool IsPublished(string culture = null) => true;
@@ -214,7 +220,7 @@ namespace Umbraco.Tests.PublishedContent
#region ContentType
- public IPublishedContentType ContentType { get; private set; }
+ public IPublishedContentType ContentType { get; set; }
#endregion
@@ -236,7 +242,7 @@ namespace Umbraco.Tests.PublishedContent
while (content != null && (property == null || property.HasValue() == false))
{
content = content.Parent;
- property = content == null ? null : content.GetProperty(alias);
+ property = content?.GetProperty(alias);
}
return property;
diff --git a/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs b/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs
index 9eee6eb32d..5af48e64b1 100644
--- a/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs
+++ b/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Linq;
using Moq;
using Newtonsoft.Json;
@@ -11,7 +10,6 @@ using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Tests.PublishedContent;
using Umbraco.Tests.TestHelpers;
-using Umbraco.Tests.TestHelpers.Stubs;
using Umbraco.Tests.Testing;
using Umbraco.Web.Routing;
@@ -56,10 +54,10 @@ namespace Umbraco.Tests.Routing
const string expected = "/media/rfeiw584/test.jpg";
var configuration = new ImageCropperConfiguration();
- var imageCropperValue = JsonConvert.SerializeObject(new ImageCropperValue
+ var imageCropperValue = new ImageCropperValue
{
Src = expected
- });
+ };
var umbracoContext = GetUmbracoContext("/", mediaUrlProviders: new[] { _mediaUrlProvider });
var publishedContent = CreatePublishedContent(Constants.PropertyEditors.Aliases.ImageCropper, imageCropperValue, configuration);
@@ -120,15 +118,28 @@ namespace Umbraco.Tests.Routing
Assert.AreEqual(daMediaUrl, resolvedUrl);
}
- private static TestPublishedContent CreatePublishedContent(string propertyEditorAlias, object propertyValue, object dataTypeConfiguration)
+ private static IPublishedContent CreatePublishedContent(string propertyEditorAlias, object propertyValue, object dataTypeConfiguration)
{
var umbracoFilePropertyType = CreatePropertyType(propertyEditorAlias, dataTypeConfiguration, ContentVariation.Nothing);
var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(),
new[] {umbracoFilePropertyType}, ContentVariation.Nothing);
- return new TestPublishedContent(contentType, 1234, Guid.NewGuid(),
- new Dictionary {{"umbracoFile", propertyValue } }, false);
+ return new SolidPublishedContent(contentType)
+ {
+ Id = 1234,
+ Key = Guid.NewGuid(),
+ Properties = new[]
+ {
+ new SolidPublishedProperty
+ {
+ Alias = "umbracoFile",
+ SolidValue = propertyValue,
+ SolidHasValue = true,
+ PropertyType = umbracoFilePropertyType
+ }
+ }
+ };
}
private static PublishedPropertyType CreatePropertyType(string propertyEditorAlias, object dataTypeConfiguration, ContentVariation variation)
diff --git a/src/Umbraco.Tests/Routing/UrlProviderTests.cs b/src/Umbraco.Tests/Routing/UrlProviderTests.cs
index ca13e06f0a..02aa95cd2e 100644
--- a/src/Umbraco.Tests/Routing/UrlProviderTests.cs
+++ b/src/Umbraco.Tests/Routing/UrlProviderTests.cs
@@ -10,8 +10,8 @@ using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Tests.LegacyXmlPublishedCache;
+using Umbraco.Tests.PublishedContent;
using Umbraco.Tests.TestHelpers;
-using Umbraco.Tests.TestHelpers.Stubs;
using Umbraco.Tests.Testing;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
@@ -142,7 +142,7 @@ namespace Umbraco.Tests.Routing
new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
}, globalSettings: globalSettings.Object);
-
+
var result = umbracoContext.UrlProvider.GetUrl(nodeId);
Assert.AreEqual(niceUrlMatch, result);
}
@@ -159,7 +159,7 @@ namespace Umbraco.Tests.Routing
var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Culture);
- var publishedContent = new TestPublishedContent(contentType, 1234, Guid.NewGuid(), new Dictionary(), false);
+ var publishedContent = new SolidPublishedContent(contentType) { Id = 1234 };
var publishedContentCache = new Mock();
publishedContentCache.Setup(x => x.GetRouteById(1234, "fr-FR"))
@@ -204,7 +204,7 @@ namespace Umbraco.Tests.Routing
var umbracoSettings = Current.Configs.Settings();
var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Culture);
- var publishedContent = new TestPublishedContent(contentType, 1234, Guid.NewGuid(), new Dictionary(), false);
+ var publishedContent = new SolidPublishedContent(contentType) { Id = 1234 };
var publishedContentCache = new Mock();
publishedContentCache.Setup(x => x.GetRouteById(1234, "fr-FR"))
@@ -258,7 +258,7 @@ namespace Umbraco.Tests.Routing
var umbracoSettings = Current.Configs.Settings();
var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Culture);
- var publishedContent = new TestPublishedContent(contentType, 1234, Guid.NewGuid(), new Dictionary(), false);
+ var publishedContent = new SolidPublishedContent(contentType) { Id = 1234 };
var publishedContentCache = new Mock();
publishedContentCache.Setup(x => x.GetRouteById(1234, "fr-FR"))
@@ -332,7 +332,7 @@ namespace Umbraco.Tests.Routing
}, globalSettings: globalSettings.Object);
//mock the Umbraco settings that we need
-
+
Assert.AreEqual("#", umbracoContext.UrlProvider.GetUrl(999999));
umbracoContext.UrlProvider.Mode = UrlMode.Absolute;
diff --git a/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs b/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs
deleted file mode 100644
index 62f93d106f..0000000000
--- a/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Umbraco.Core.Models.PublishedContent;
-using Umbraco.Web.PublishedCache;
-
-namespace Umbraco.Tests.TestHelpers.Stubs
-{
- internal class TestPublishedContent : PublishedElement, IPublishedContent
- {
- public TestPublishedContent(IPublishedContentType contentType, int id, Guid key, Dictionary values, bool previewing, Dictionary cultures = null)
- : base(contentType, key, values, previewing)
- {
- Id = id;
- Cultures = cultures ?? new Dictionary();
- }
-
- public int Id { get; }
- public int? TemplateId { get; set; }
- public int SortOrder { get; set; }
- public string Name { get; set; }
- public IVariationContextAccessor VariationContextAccessor { get; set; }
- public IReadOnlyDictionary Cultures { get; set; }
- public string UrlSegment { get; set; }
- public string DocumentTypeAlias => ContentType.Alias;
- public int DocumentTypeId { get; set; }
- public string WriterName { get; set; }
- public string CreatorName { get; set; }
- public int WriterId { get; set; }
- public int CreatorId { get; set; }
- public string Path { get; set; }
- public DateTime CreateDate { get; set; }
- public DateTime UpdateDate { get; set; }
- public Guid Version { get; set; }
- public int Level { get; set; }
- public string Url { get; set; }
- public PublishedItemType ItemType => ContentType.ItemType;
- public bool IsDraft(string culture = null) => false;
- public bool IsPublished(string culture = null) => true;
- public IPublishedContent Parent { get; set; }
- public IEnumerable Children { get; set; }
- public IEnumerable ChildrenForAllCultures => Children;
-
- // copied from PublishedContentBase
- public IPublishedProperty GetProperty(string alias, bool recurse)
- {
- var property = GetProperty(alias);
- if (recurse == false) return property;
-
- IPublishedContent content = this;
- var firstNonNullProperty = property;
- while (content != null && (property == null || property.HasValue() == false))
- {
- content = content.Parent;
- property = content?.GetProperty(alias);
- if (firstNonNullProperty == null && property != null) firstNonNullProperty = property;
- }
-
- // if we find a content with the property with a value, return that property
- // if we find no content with the property, return null
- // if we find a content with the property without a value, return that property
- // have to save that first property while we look further up, hence firstNonNullProperty
-
- return property != null && property.HasValue() ? property : firstNonNullProperty;
- }
- }
-}
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index cd3155c7c3..4f4a83dc26 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -206,7 +206,6 @@
-
diff --git a/src/Umbraco.Web/PublishedCache/IPublishedCache.cs b/src/Umbraco.Web/PublishedCache/IPublishedCache.cs
index 33094221f7..0370088f77 100644
--- a/src/Umbraco.Web/PublishedCache/IPublishedCache.cs
+++ b/src/Umbraco.Web/PublishedCache/IPublishedCache.cs
@@ -84,16 +84,18 @@ namespace Umbraco.Web.PublishedCache
/// Gets contents at root.
///
/// A value indicating whether to consider unpublished content.
+ /// A culture.
/// The contents.
/// The value of overrides defaults.
- IEnumerable GetAtRoot(bool preview);
+ IEnumerable GetAtRoot(bool preview, string culture = null);
///
/// Gets contents at root.
///
+ /// A culture.
/// The contents.
/// Considers published or unpublished content depending on defaults.
- IEnumerable GetAtRoot();
+ IEnumerable GetAtRoot(string culture = null);
///
/// Gets a content resulting from an XPath query.
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs
index 4dcee5eb24..fa879b7879 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs
@@ -1,20 +1,15 @@
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.XPath;
using Umbraco.Core;
using Umbraco.Core.Cache;
-using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
-using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
-using Umbraco.Core.Services;
using Umbraco.Core.Xml;
using Umbraco.Core.Xml.XPath;
using Umbraco.Web.PublishedCache.NuCache.Navigable;
-using Umbraco.Web.Routing;
namespace Umbraco.Web.PublishedCache.NuCache
{
@@ -25,6 +20,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
private readonly IAppCache _elementsCache;
private readonly IDomainCache _domainCache;
private readonly IGlobalSettings _globalSettings;
+ private readonly IVariationContextAccessor _variationContextAccessor;
#region Constructor
@@ -33,7 +29,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
// it's too late for UmbracoContext which has captured previewDefault and stuff into these ctor vars
// but, no, UmbracoContext returns snapshot.Content which comes from elements SO a resync should create a new cache
- public ContentCache(bool previewDefault, ContentStore.Snapshot snapshot, IAppCache snapshotCache, IAppCache elementsCache, IDomainCache domainCache, IGlobalSettings globalSettings)
+ public ContentCache(bool previewDefault, ContentStore.Snapshot snapshot, IAppCache snapshotCache, IAppCache elementsCache, IDomainCache domainCache, IGlobalSettings globalSettings, IVariationContextAccessor variationContextAccessor)
: base(previewDefault)
{
_snapshot = snapshot;
@@ -41,6 +37,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
_elementsCache = elementsCache;
_domainCache = domainCache;
_globalSettings = globalSettings;
+ _variationContextAccessor = variationContextAccessor;
}
private bool HideTopLevelNodeFromPath => _globalSettings.HideTopLevelNodeFromPath;
@@ -241,7 +238,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
var guidUdi = contentId as GuidUdi;
if (guidUdi == null)
throw new ArgumentException($"Udi must be of type {typeof(GuidUdi).Name}.", nameof(contentId));
-
+
if (guidUdi.EntityType != Constants.UdiEntityType.Document)
throw new ArgumentException($"Udi entity type must be \"{Constants.UdiEntityType.Document}\".", nameof(contentId));
@@ -256,11 +253,18 @@ namespace Umbraco.Web.PublishedCache.NuCache
return preview || n.PublishedModel != null;
}
- public override IEnumerable GetAtRoot(bool preview)
+ IEnumerable INavigableData.GetAtRoot(bool preview) => GetAtRoot(preview);
+
+ public override IEnumerable GetAtRoot(bool preview, string culture = null)
{
+ // handle context culture for variant
+ if (culture == null)
+ culture = _variationContextAccessor?.VariationContext?.Culture ?? "";
+
// both .Draft and .Published cannot be null at the same time
// root is already sorted by sortOrder, and does not contain nulls
- return _snapshot.GetAtRoot().Select(n => GetNodePublishedContent(n, preview));
+ var atRoot = _snapshot.GetAtRoot().Select(n => GetNodePublishedContent(n, preview));
+ return culture == "*" ? atRoot : atRoot.Where(x => x.IsInvariantOrHasCulture(culture));
}
private static IPublishedContent GetNodePublishedContent(ContentNode node, bool preview)
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/MediaCache.cs b/src/Umbraco.Web/PublishedCache/NuCache/MediaCache.cs
index fc04d9d1b3..182086ed7f 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/MediaCache.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/MediaCache.cs
@@ -14,17 +14,15 @@ namespace Umbraco.Web.PublishedCache.NuCache
internal class MediaCache : PublishedCacheBase, IPublishedMediaCache, INavigableData, IDisposable
{
private readonly ContentStore.Snapshot _snapshot;
- private readonly IAppCache _snapshotCache;
- private readonly IAppCache _elementsCache;
+ private readonly IVariationContextAccessor _variationContextAccessor;
#region Constructors
- public MediaCache(bool previewDefault, ContentStore.Snapshot snapshot, IAppCache snapshotCache, IAppCache elementsCache)
+ public MediaCache(bool previewDefault, ContentStore.Snapshot snapshot, IVariationContextAccessor variationContextAccessor)
: base(previewDefault)
{
_snapshot = snapshot;
- _snapshotCache = snapshotCache;
- _elementsCache = elementsCache;
+ _variationContextAccessor = variationContextAccessor;
}
#endregion
@@ -65,30 +63,16 @@ namespace Umbraco.Web.PublishedCache.NuCache
return n != null;
}
- public override IEnumerable GetAtRoot(bool preview)
+ IEnumerable INavigableData.GetAtRoot(bool preview) => GetAtRoot(preview);
+
+ public override IEnumerable GetAtRoot(bool preview, string culture = null)
{
- if (PublishedSnapshotService.CacheContentCacheRoots == false)
- return GetAtRootNoCache();
+ // handle context culture for variant
+ if (culture == null)
+ culture = _variationContextAccessor?.VariationContext?.Culture ?? "";
- var cache = preview == false || PublishedSnapshotService.FullCacheWhenPreviewing
- ? _elementsCache
- : _snapshotCache;
-
- if (cache == null)
- return GetAtRootNoCache();
-
- // note: ToArray is important here, we want to cache the result, not the function!
- return (IEnumerable)cache.Get(
- CacheKeys.MediaCacheRoots(false), // ignore preview, only 1 key!
- () => GetAtRootNoCache().ToArray());
- }
-
- private IEnumerable GetAtRootNoCache()
- {
- var c = _snapshot.GetAtRoot();
-
- // ignore preview, there's only draft for media
- return c.Select(n => n.PublishedModel);
+ var atRoot = _snapshot.GetAtRoot().Select(x => x.PublishedModel);
+ return culture == "*" ? atRoot : atRoot.Where(x => x.IsInvariantOrHasCulture(culture));
}
public override bool HasContent(bool preview)
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
index 67f219be21..1995e8b424 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
@@ -186,11 +186,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
{
get
{
- if (!ContentType.VariesByCulture())
- return EmptyCultures;
-
if (_cultures != null) return _cultures;
+ if (!ContentType.VariesByCulture())
+ return _cultures = new Dictionary
+ {
+ { "", new PublishedCultureInfo("", ContentData.Name, _urlSegment, CreateDate) }
+ };
+
if (ContentData.CultureInfos == null)
throw new Exception("panic: _contentDate.CultureInfos is null.");
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
index 5a3672ed57..7a7682a797 100755
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
@@ -63,18 +63,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
// so making it configurable.
public static readonly bool FullCacheWhenPreviewing = true;
- // define constant - determines whether to cache the published content
- // objects (in the elements cache, or snapshot cache, depending on preview)
- // or to re-fetch them all the time. caching is faster but uses more
- // memory. not sure what we want.
- public static readonly bool CachePublishedContentChildren = true;
-
- // define constant - determines whether to cache the content cache root
- // objects (in the elements cache, or snapshot cache, depending on preview)
- // or to re-fetch them all the time. caching is faster but uses more
- // memory - not sure what we want.
- public static readonly bool CacheContentCacheRoots = true;
-
#region Constructors
//private static int _singletonCheck;
@@ -1070,8 +1058,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
return new PublishedSnapshot.PublishedSnapshotElements
{
- ContentCache = new ContentCache(previewDefault, contentSnap, snapshotCache, elementsCache, domainCache, _globalSettings),
- MediaCache = new MediaCache(previewDefault, mediaSnap, snapshotCache, elementsCache),
+ ContentCache = new ContentCache(previewDefault, contentSnap, snapshotCache, elementsCache, domainCache, _globalSettings, VariationContextAccessor),
+ MediaCache = new MediaCache(previewDefault, mediaSnap, VariationContextAccessor),
MemberCache = new MemberCache(previewDefault, snapshotCache, _serviceContext.MemberService, memberTypeCache, PublishedSnapshotAccessor, VariationContextAccessor, _entitySerializer),
DomainCache = domainCache,
SnapshotCache = snapshotCache,
diff --git a/src/Umbraco.Web/PublishedCache/PublishedCacheBase.cs b/src/Umbraco.Web/PublishedCache/PublishedCacheBase.cs
index d726664db0..1f637663e5 100644
--- a/src/Umbraco.Web/PublishedCache/PublishedCacheBase.cs
+++ b/src/Umbraco.Web/PublishedCache/PublishedCacheBase.cs
@@ -37,11 +37,11 @@ namespace Umbraco.Web.PublishedCache
public bool HasById(int contentId)
=> HasById(PreviewDefault, contentId);
- public abstract IEnumerable GetAtRoot(bool preview);
+ public abstract IEnumerable GetAtRoot(bool preview, string culture = null);
- public IEnumerable GetAtRoot()
+ public IEnumerable GetAtRoot(string culture = null)
{
- return GetAtRoot(PreviewDefault);
+ return GetAtRoot(PreviewDefault, culture);
}
public abstract IPublishedContent GetSingleByXPath(bool preview, string xpath, XPathVariable[] vars);
diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs
index fbfc52f4d8..d7283a1e90 100644
--- a/src/Umbraco.Web/PublishedContentExtensions.cs
+++ b/src/Umbraco.Web/PublishedContentExtensions.cs
@@ -833,7 +833,7 @@ namespace Umbraco.Web
if (content == null) throw new ArgumentNullException(nameof(content));
if (orSelf) yield return content;
- foreach (var desc in content.Children(culture).SelectMany(x => x.EnumerateDescendants()))
+ foreach (var desc in content.Children(culture).SelectMany(x => x.EnumerateDescendants(culture)))
yield return desc;
}
@@ -841,7 +841,7 @@ namespace Umbraco.Web
{
yield return content;
- foreach (var desc in content.Children(culture).SelectMany(x => x.EnumerateDescendants()))
+ foreach (var desc in content.Children(culture).SelectMany(x => x.EnumerateDescendants(culture)))
yield return desc;
}