Merge branch 'v8/dev' of https://github.com/umbraco/Umbraco-CMS into pr/6691_vary-by-culture-set-unset-culture-flag-only

# Conflicts:
#	src/Umbraco.Web/Models/Mapping/ContentTypeMapDefinition.cs
This commit is contained in:
Daniël Knippers
2019-11-22 09:08:27 +01:00
506 changed files with 11554 additions and 6778 deletions

View File

@@ -4,6 +4,7 @@ using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Tests.Composing
@@ -35,7 +36,7 @@ namespace Umbraco.Tests.Composing
.Returns(() => factoryFactory?.Invoke(mockedFactory));
var logger = new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>());
var typeLoader = new TypeLoader(Mock.Of<IAppPolicyCache>(), "", logger);
var typeLoader = new TypeLoader(Mock.Of<IAppPolicyCache>(), IOHelper.MapPath("~/App_Data/TEMP"), logger);
var composition = new Composition(mockedRegister, typeLoader, logger, Mock.Of<IRuntimeState>());
// create the factory, ensure it is the mocked factory

View File

@@ -165,7 +165,7 @@ namespace Umbraco.Tests.Composing
Assert.IsTrue(TypeHelper.MatchType(typeof(int?), typeof(Nullable<>)));
Assert.IsTrue(TypeHelper.MatchType(typeof(Derived<int>), typeof(Object)));
Assert.IsTrue(TypeHelper.MatchType(typeof(Derived<int>), typeof(object)));
Assert.IsFalse(TypeHelper.MatchType(typeof(Derived<int>), typeof(List<>)));
Assert.IsFalse(TypeHelper.MatchType(typeof(Derived<int>), typeof(IEnumerable<>)));
Assert.IsTrue(TypeHelper.MatchType(typeof(Derived<int>), typeof(Base<int>)));

View File

@@ -67,7 +67,7 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings
[Test]
public void PreviewBadge()
{
Assert.AreEqual(SettingsSection.Content.PreviewBadge, @"<a id=""umbracoPreviewBadge"" style=""z-index:99999; position: absolute; top: 0; right: 0; border: 0; width: 149px; height: 149px; background: url('{0}/assets/img/preview-mode-badge.png') no-repeat;"" href=""#"" OnClick=""javascript:window.top.location.href = '{0}/preview/end?redir={1}'""><span style=""display:none;"">In Preview Mode - click to end</span></a>");
Assert.AreEqual(SettingsSection.Content.PreviewBadge, @"<div id=""umbracoPreviewBadge"" class=""umbraco-preview-badge""><span class=""umbraco-preview-badge__header"">Preview mode</span><a href=""{0}/preview/end?redir={1}"" class=""umbraco-preview-badge__end""><svg viewBox=""0 0 100 100"" xmlns=""http://www.w3.org/2000/svg""><title>Click to end</title><path d=""M5273.1 2400.1v-2c0-2.8-5-4-9.7-4s-9.7 1.3-9.7 4v2a7 7 0 002 4.9l5 4.9c.3.3.4.6.4 1v6.4c0 .4.2.7.6.8l2.9.9c.5.1 1-.2 1-.8v-7.2c0-.4.2-.7.4-1l5.1-5a7 7 0 002-4.9zm-9.7-.1c-4.8 0-7.4-1.3-7.5-1.8.1-.5 2.7-1.8 7.5-1.8s7.3 1.3 7.5 1.8c-.2.5-2.7 1.8-7.5 1.8z""/><path d=""M5268.4 2410.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1s-.4-1-1-1h-4.3zM5272.7 2413.7h-4.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1s-.4-1-1-1zM5272.7 2417h-4.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1 0-.5-.4-1-1-1z""/><path d=""M78.2 13l-8.7 11.7a32.5 32.5 0 11-51.9 25.8c0-10.3 4.7-19.7 12.9-25.8L21.8 13a47 47 0 1056.4 0z""/><path d=""M42.7 2.5h14.6v49.4H42.7z""/></svg></a></div><style type=""text/css"">.umbraco-preview-badge {{position: absolute;top: 1em;right: 1em;display: inline-flex;background: #1b264f;color: #fff;padding: 1em;font-size: 12px;z-index: 99999999;justify-content: center;align-items: center;box-shadow: 0 10px 50px rgba(0, 0, 0, .1), 0 6px 20px rgba(0, 0, 0, .16);line-height: 1;}}.umbraco-preview-badge__header {{font-weight: bold;}}.umbraco-preview-badge__end {{width: 3em;padding: 1em;margin: -1em -1em -1em 2em;display: flex;flex-shrink: 0;align-items: center;align-self: stretch;}}.umbraco-preview-badge__end:hover,.umbraco-preview-badge__end:focus {{background: #f5c1bc;}}.umbraco-preview-badge__end svg {{fill: #fff;width:1em;}}</style>");
}
[Test]
public void ResolveUrlsFromTextString()

View File

@@ -41,9 +41,7 @@
</notifications>
<PreviewBadge>
<![CDATA[
<a id="umbracoPreviewBadge" style="z-index:99999; position: absolute; top: 0; right: 0; border: 0; width: 149px; height: 149px; background: url('{0}/assets/img/preview-mode-badge.png') no-repeat;" href="#" OnClick="javascript:window.top.location.href = '{0}/preview/end?redir={1}'"><span style="display:none;">In Preview Mode - click to end</span></a>
]]></PreviewBadge>
<![CDATA[<div id="umbracoPreviewBadge" class="umbraco-preview-badge"><span class="umbraco-preview-badge__header">Preview mode</span><a href="{0}/preview/end?redir={1}" class="umbraco-preview-badge__end"><svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><title>Click to end</title><path d="M5273.1 2400.1v-2c0-2.8-5-4-9.7-4s-9.7 1.3-9.7 4v2a7 7 0 002 4.9l5 4.9c.3.3.4.6.4 1v6.4c0 .4.2.7.6.8l2.9.9c.5.1 1-.2 1-.8v-7.2c0-.4.2-.7.4-1l5.1-5a7 7 0 002-4.9zm-9.7-.1c-4.8 0-7.4-1.3-7.5-1.8.1-.5 2.7-1.8 7.5-1.8s7.3 1.3 7.5 1.8c-.2.5-2.7 1.8-7.5 1.8z"/><path d="M5268.4 2410.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1s-.4-1-1-1h-4.3zM5272.7 2413.7h-4.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1s-.4-1-1-1zM5272.7 2417h-4.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1 0-.5-.4-1-1-1z"/><path d="M78.2 13l-8.7 11.7a32.5 32.5 0 11-51.9 25.8c0-10.3 4.7-19.7 12.9-25.8L21.8 13a47 47 0 1056.4 0z"/><path d="M42.7 2.5h14.6v49.4H42.7z"/></svg></a></div><style type="text/css">.umbraco-preview-badge {{position: absolute;top: 1em;right: 1em;display: inline-flex;background: #1b264f;color: #fff;padding: 1em;font-size: 12px;z-index: 99999999;justify-content: center;align-items: center;box-shadow: 0 10px 50px rgba(0, 0, 0, .1), 0 6px 20px rgba(0, 0, 0, .16);line-height: 1;}}.umbraco-preview-badge__header {{font-weight: bold;}}.umbraco-preview-badge__end {{width: 3em;padding: 1em;margin: -1em -1em -1em 2em;display: flex;flex-shrink: 0;align-items: center;align-self: stretch;}}.umbraco-preview-badge__end:hover,.umbraco-preview-badge__end:focus {{background: #f5c1bc;}}.umbraco-preview-badge__end svg {{fill: #fff;width:1em;}}</style>]]></PreviewBadge>
<!-- How Umbraco should handle errors during macro execution. Can be one of the following values:
- inline - show an inline error within the macro but allow the page to continue rendering. Historial Umbraco behaviour.

View File

@@ -101,7 +101,7 @@ namespace Umbraco.Tests.IO
Assert.AreEqual(Path.Combine(basePath, @"foo\bar.tmp"), path);
// that path is invalid as it would be outside the root directory
Assert.Throws<FileSecurityException>(() => _fileSystem.GetFullPath("../../foo.tmp"));
Assert.Throws<UnauthorizedAccessException>(() => _fileSystem.GetFullPath("../../foo.tmp"));
// a very long path, which ends up being very long, works
path = Repeat("bah/bah/", 50);

View File

@@ -238,7 +238,7 @@ namespace Umbraco.Tests.IO
var sfs = new PhysicalFileSystem(path + "/ShadowSystem/", "ignore");
var ss = new ShadowFileSystem(fs, sfs);
Assert.Throws<FileSecurityException>(() =>
Assert.Throws<UnauthorizedAccessException>(() =>
{
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
ss.AddFile("../../f1.txt", ms);

View File

@@ -21,7 +21,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
/// <summary>
/// Implements a published snapshot service.
/// </summary>
internal class PublishedSnapshotService : PublishedSnapshotServiceBase
internal class XmlPublishedSnapshotService : PublishedSnapshotServiceBase
{
private readonly XmlStore _xmlStore;
private readonly RoutesCache _routesCache;
@@ -41,7 +41,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
#region Constructors
// used in WebBootManager + tests
public PublishedSnapshotService(ServiceContext serviceContext,
public XmlPublishedSnapshotService(ServiceContext serviceContext,
IPublishedContentTypeFactory publishedContentTypeFactory,
IScopeProvider scopeProvider,
IAppCache requestCache,
@@ -65,7 +65,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
}
// used in some tests
internal PublishedSnapshotService(ServiceContext serviceContext,
internal XmlPublishedSnapshotService(ServiceContext serviceContext,
IPublishedContentTypeFactory publishedContentTypeFactory,
IScopeProvider scopeProvider,
IAppCache requestCache,

View File

@@ -32,7 +32,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
/// Represents the Xml storage for the Xml published cache.
/// </summary>
/// <remarks>
/// <para>One instance of <see cref="XmlStore"/> is instantiated by the <see cref="PublishedSnapshotService"/> and
/// <para>One instance of <see cref="XmlStore"/> is instantiated by the <see cref="XmlPublishedSnapshotService"/> and
/// then passed to all <see cref="PublishedContentCache"/> instances that are created (one per request).</para>
/// <para>This class should *not* be public.</para>
/// </remarks>

View File

@@ -621,7 +621,9 @@ namespace Umbraco.Tests.Models.Mapping
Validation = new PropertyTypeValidation()
{
Mandatory = true,
Pattern = "xyz"
MandatoryMessage = "Please enter a value",
Pattern = "xyz",
PatternMessage = "Please match the pattern",
}
};
@@ -634,7 +636,9 @@ namespace Umbraco.Tests.Models.Mapping
Assert.AreEqual(basic.DataTypeId, result.DataTypeId);
Assert.AreEqual(basic.Label, result.Name);
Assert.AreEqual(basic.Validation.Mandatory, result.Mandatory);
Assert.AreEqual(basic.Validation.MandatoryMessage, result.MandatoryMessage);
Assert.AreEqual(basic.Validation.Pattern, result.ValidationRegExp);
Assert.AreEqual(basic.Validation.PatternMessage, result.ValidationRegExpMessage);
}
[Test]
@@ -655,7 +659,9 @@ namespace Umbraco.Tests.Models.Mapping
Validation = new PropertyTypeValidation()
{
Mandatory = true,
Pattern = "xyz"
MandatoryMessage = "Please enter a value",
Pattern = "xyz",
PatternMessage = "Please match the pattern",
}
};
@@ -668,7 +674,9 @@ namespace Umbraco.Tests.Models.Mapping
Assert.AreEqual(basic.DataTypeId, result.DataTypeId);
Assert.AreEqual(basic.Label, result.Name);
Assert.AreEqual(basic.Validation.Mandatory, result.Mandatory);
Assert.AreEqual(basic.Validation.MandatoryMessage, result.MandatoryMessage);
Assert.AreEqual(basic.Validation.Pattern, result.ValidationRegExp);
Assert.AreEqual(basic.Validation.PatternMessage, result.ValidationRegExpMessage);
}
[Test]
@@ -951,7 +959,7 @@ namespace Umbraco.Tests.Models.Mapping
Name = "Tab 1",
SortOrder = 0,
Inherited = false,
Properties = new []
Properties = new[]
{
new MemberPropertyTypeBasic
{
@@ -965,7 +973,7 @@ namespace Umbraco.Tests.Models.Mapping
Validation = new PropertyTypeValidation
{
Mandatory = false,
Pattern = ""
Pattern = string.Empty
},
SortOrder = 0,
DataTypeId = 555
@@ -1000,7 +1008,7 @@ namespace Umbraco.Tests.Models.Mapping
Name = "Tab 1",
SortOrder = 0,
Inherited = false,
Properties = new []
Properties = new[]
{
new PropertyTypeBasic
{
@@ -1011,7 +1019,7 @@ namespace Umbraco.Tests.Models.Mapping
Validation = new PropertyTypeValidation
{
Mandatory = false,
Pattern = ""
Pattern = string.Empty
},
SortOrder = 0,
DataTypeId = 555
@@ -1052,7 +1060,7 @@ namespace Umbraco.Tests.Models.Mapping
Name = "Tab 1",
SortOrder = 0,
Inherited = false,
Properties = new []
Properties = new[]
{
new PropertyTypeBasic
{
@@ -1063,7 +1071,7 @@ namespace Umbraco.Tests.Models.Mapping
Validation = new PropertyTypeValidation
{
Mandatory = false,
Pattern = ""
Pattern = string.Empty
},
SortOrder = 0,
DataTypeId = 555
@@ -1109,7 +1117,7 @@ namespace Umbraco.Tests.Models.Mapping
Validation = new PropertyTypeValidation
{
Mandatory = false,
Pattern = ""
Pattern = string.Empty
},
SortOrder = 0,
DataTypeId = 555
@@ -1133,7 +1141,7 @@ namespace Umbraco.Tests.Models.Mapping
Validation = new PropertyTypeValidation
{
Mandatory = false,
Pattern = ""
Pattern = string.Empty
},
SortOrder = 0,
DataTypeId = 555
@@ -1187,7 +1195,7 @@ namespace Umbraco.Tests.Models.Mapping
Validation = new PropertyTypeValidation
{
Mandatory = false,
Pattern = ""
Pattern = string.Empty
},
SortOrder = 0,
DataTypeId = 555
@@ -1211,7 +1219,7 @@ namespace Umbraco.Tests.Models.Mapping
Validation = new PropertyTypeValidation
{
Mandatory = false,
Pattern = ""
Pattern = string.Empty
},
SortOrder = 0,
DataTypeId = 555

View File

@@ -57,6 +57,9 @@ namespace Umbraco.Tests.Models
[TestCase("1,-1", "1", "1")] // was an issue
[TestCase("-1,1", "1", "1")] // was an issue
[TestCase("-1", "", "-1")]
[TestCase("", "-1", "-1")]
public void CombineStartNodes(string groupSn, string userSn, string expected)
{
// 1

View File

@@ -5,7 +5,6 @@ using System.Threading;
using NPoco;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing;
@@ -37,7 +36,7 @@ namespace Umbraco.Tests.Persistence
{
using (var scope = ScopeProvider.CreateScope())
{
scope.Database.AcquireLockNodeReadLock(Constants.Locks.Servers);
scope.ReadLock(Constants.Locks.Servers);
scope.Complete();
}
}
@@ -62,7 +61,7 @@ namespace Umbraco.Tests.Persistence
{
try
{
scope.Database.AcquireLockNodeReadLock(Constants.Locks.Servers);
scope.ReadLock(Constants.Locks.Servers);
lock (locker)
{
acquired++;
@@ -131,7 +130,7 @@ namespace Umbraco.Tests.Persistence
if (entered == threadCount) m1.Set();
}
ms[ic].WaitOne();
scope.Database.AcquireLockNodeWriteLock(Constants.Locks.Servers);
scope.WriteLock(Constants.Locks.Servers);
lock (locker)
{
acquired++;
@@ -221,7 +220,7 @@ namespace Umbraco.Tests.Persistence
{
otherEv.WaitOne();
Console.WriteLine($"[{id1}] WAIT {id1}");
scope.Database.AcquireLockNodeWriteLock(id1);
scope.WriteLock(id1);
Console.WriteLine($"[{id1}] GRANT {id1}");
WriteLocks(scope.Database);
myEv.Set();
@@ -232,7 +231,7 @@ namespace Umbraco.Tests.Persistence
Thread.Sleep(200); // cannot wait due to deadlock... just give it a bit of time
Console.WriteLine($"[{id1}] WAIT {id2}");
scope.Database.AcquireLockNodeWriteLock(id2);
scope.WriteLock(id2);
Console.WriteLine($"[{id1}] GRANT {id2}");
WriteLocks(scope.Database);
}
@@ -284,7 +283,7 @@ namespace Umbraco.Tests.Persistence
{
otherEv.WaitOne();
Console.WriteLine($"[{id}] WAIT {id}");
scope.Database.AcquireLockNodeWriteLock(id);
scope.WriteLock(id);
Console.WriteLine($"[{id}] GRANT {id}");
WriteLocks(scope.Database);
myEv.Set();

View File

@@ -28,6 +28,68 @@ namespace Umbraco.Tests.Persistence.Repositories
return new EntityContainerRepository(scopeAccessor, AppCaches.Disabled, Logger, Constants.ObjectTypes.DataTypeContainer);
}
[Test]
public void Can_Find_Usages()
{
var provider = TestObjects.GetScopeProvider(Logger);
using (provider.CreateScope())
{
var dtRepo = CreateRepository();
IDataType dataType1 = new DataType(new RadioButtonsPropertyEditor(Logger, ServiceContext.TextService)) { Name = "dt1" };
dtRepo.Save(dataType1);
IDataType dataType2 = new DataType(new RadioButtonsPropertyEditor(Logger, ServiceContext.TextService)) { Name = "dt2" };
dtRepo.Save(dataType2);
var ctRepo = Factory.GetInstance<IContentTypeRepository>();
IContentType ct = new ContentType(-1)
{
Alias = "ct1",
Name = "CT1",
AllowedAsRoot = true,
Icon = "icon-home",
PropertyGroups = new PropertyGroupCollection
{
new PropertyGroup(true)
{
Name = "PG1",
PropertyTypes = new PropertyTypeCollection(true)
{
new PropertyType(dataType1, "pt1")
{
Name = "PT1"
},
new PropertyType(dataType1, "pt2")
{
Name = "PT2"
},
new PropertyType(dataType2, "pt3")
{
Name = "PT3"
}
}
}
}
};
ctRepo.Save(ct);
var usages = dtRepo.FindUsages(dataType1.Id);
var key = usages.First().Key;
Assert.AreEqual(ct.Key, ((GuidUdi)key).Guid);
Assert.AreEqual(2, usages[key].Count());
Assert.AreEqual("pt1", usages[key].ElementAt(0));
Assert.AreEqual("pt2", usages[key].ElementAt(1));
usages = dtRepo.FindUsages(dataType2.Id);
key = usages.First().Key;
Assert.AreEqual(ct.Key, ((GuidUdi)key).Guid);
Assert.AreEqual(1, usages[key].Count());
Assert.AreEqual("pt3", usages[key].ElementAt(0));
}
}
[Test]
public void Can_Move()
{

View File

@@ -1,4 +1,5 @@
using System.Globalization;
using System;
using System.Globalization;
using System.Linq;
using Moq;
using NUnit.Framework;
@@ -297,6 +298,24 @@ namespace Umbraco.Tests.Persistence.Repositories
}
}
[Test]
public void Perform_Update_With_Existing_Culture()
{
// Arrange
var provider = TestObjects.GetScopeProvider(Logger);
using (var scope = provider.CreateScope())
{
var repository = CreateRepository(provider);
// Act
var language = repository.Get(5);
language.IsoCode = "da-DK";
language.CultureName = "da-DK";
Assert.Throws<InvalidOperationException>(() => repository.Save(language));
}
}
[Test]
public void Can_Perform_Delete_On_LanguageRepository()
{

View File

@@ -7,6 +7,7 @@ using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Persistence.Repositories.Implement;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing;
using System;
namespace Umbraco.Tests.Persistence.Repositories
{
@@ -77,7 +78,7 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.AreEqual("/Views/Partials/path-2/test-path-3.cshtml", partialView.VirtualPath);
partialView = new PartialView(PartialViewType.PartialView, "\\test-path-4.cshtml") { Content = "// partialView" };
Assert.Throws<FileSecurityException>(() => // fixed in 7.3 - 7.2.8 used to strip the \
Assert.Throws<UnauthorizedAccessException>(() => // fixed in 7.3 - 7.2.8 used to strip the \
{
repository.Save(partialView);
});
@@ -86,11 +87,11 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.IsNull(partialView);
// fixed in 7.3 - 7.2.8 used to...
Assert.Throws<FileSecurityException>(() =>
Assert.Throws<UnauthorizedAccessException>(() =>
{
partialView = (PartialView) repository.Get("\\test-path-4.cshtml"); // outside the filesystem, does not exist
});
Assert.Throws<FileSecurityException>(() =>
Assert.Throws<UnauthorizedAccessException>(() =>
{
partialView = (PartialView) repository.Get("../../packages.config"); // outside the filesystem, exists
});

View File

@@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
using System.Linq;
using System.Text;
using Moq;
@@ -301,7 +302,7 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath);
script = new Script("\\test-path-4.js") { Content = "// script" };
Assert.Throws<FileSecurityException>(() => // fixed in 7.3 - 7.2.8 used to strip the \
Assert.Throws<UnauthorizedAccessException>(() => // fixed in 7.3 - 7.2.8 used to strip the \
{
repository.Save(script);
});
@@ -310,11 +311,11 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.IsNull(script);
// fixed in 7.3 - 7.2.8 used to...
Assert.Throws<FileSecurityException>(() =>
Assert.Throws<UnauthorizedAccessException>(() =>
{
script = repository.Get("\\test-path-4.js"); // outside the filesystem, does not exist
});
Assert.Throws<FileSecurityException>(() =>
Assert.Throws<UnauthorizedAccessException>(() =>
{
script = repository.Get("../packages.config"); // outside the filesystem, exists
});

View File

@@ -1,4 +1,5 @@
using System.Data;
using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
@@ -284,7 +285,7 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.AreEqual("/css/path-2/test-path-3.css", stylesheet.VirtualPath);
stylesheet = new Stylesheet("\\test-path-4.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" };
Assert.Throws<FileSecurityException>(() => // fixed in 7.3 - 7.2.8 used to strip the \
Assert.Throws<UnauthorizedAccessException>(() => // fixed in 7.3 - 7.2.8 used to strip the \
{
repository.Save(stylesheet);
});
@@ -294,11 +295,11 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.IsNull(stylesheet);
// fixed in 7.3 - 7.2.8 used to...
Assert.Throws<FileSecurityException>(() =>
Assert.Throws<UnauthorizedAccessException>(() =>
{
stylesheet = repository.Get("\\test-path-4.css"); // outside the filesystem, does not exist
});
Assert.Throws<FileSecurityException>(() =>
Assert.Throws<UnauthorizedAccessException>(() =>
{
stylesheet = repository.Get("../packages.config"); // outside the filesystem, exists
});

View File

@@ -14,7 +14,7 @@ namespace Umbraco.Tests.Persistence
public void ReadLockNonExisting()
{
var provider = TestObjects.GetScopeProvider(Logger);
Assert.Throws<Exception>(() =>
Assert.Throws<ArgumentException>(() =>
{
using (var scope = provider.CreateScope())
{
@@ -39,7 +39,7 @@ namespace Umbraco.Tests.Persistence
public void WriteLockNonExisting()
{
var provider = TestObjects.GetScopeProvider(Logger);
Assert.Throws<Exception>(() =>
Assert.Throws<ArgumentException>(() =>
{
using (var scope = provider.CreateScope())
{

View File

@@ -264,7 +264,7 @@ namespace Umbraco.Tests.Published
public override bool HasValue(string culture = null, string segment = null) => _hasValue;
public override object GetSourceValue(string culture = null, string segment = null) => _sourceValue;
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();
public override object GetXPathValue(string culture = null, string segment = null) => throw new InvalidOperationException("This method won't be implemented.");
}
}
}

View File

@@ -41,6 +41,12 @@ namespace Umbraco.Tests.PublishedContent
private ContentType _contentTypeVariant;
private TestDataSource _source;
[TearDown]
public void Teardown()
{
_snapshotService?.Dispose();
}
private void Init(IEnumerable<ContentNodeKit> kits)
{
Current.Reset();
@@ -213,22 +219,24 @@ namespace Umbraco.Tests.PublishedContent
var level = path.Count(x => x == ',');
var now = DateTime.Now;
var contentData = new ContentData
{
Name = "N" + id,
Published = true,
TemplateId = 0,
VersionId = 1,
VersionDate = now,
WriterId = 0,
Properties = new Dictionary<string, PropertyData[]>(),
CultureInfos = new Dictionary<string, CultureVariation>()
};
return new ContentNodeKit
{
ContentTypeId = _contentTypeInvariant.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<string, PropertyData[]>(),
CultureInfos = new Dictionary<string, CultureVariation>()
}
PublishedData = contentData
};
}
@@ -333,7 +341,7 @@ namespace Umbraco.Tests.PublishedContent
CultureInfos = GetCultureInfos(id, now)
};
var withDraft = id%2==0;
var withDraft = id % 2 == 0;
var withPublished = !withDraft;
return new ContentNodeKit
@@ -1063,6 +1071,153 @@ namespace Umbraco.Tests.PublishedContent
AssertLinkedNode(child3.contentNode, 1, 2, -1, -1, -1);
}
[Test]
public void Refresh_Node_Ensures_Linked_list()
{
// NOTE: these tests are not using real scopes, in which case a Scope does not control
// how the snapshots generations work. We are forcing new snapshot generations manually.
IEnumerable<ContentNodeKit> GetKits()
{
var paths = new Dictionary<int, string> { { -1, "-1" } };
//root
yield return CreateInvariantKit(100, -1, 1, paths);
//site
yield return CreateInvariantKit(2, 100, 1, paths);
yield return CreateInvariantKit(1, 100, 2, paths); //middle child
yield return CreateInvariantKit(3, 100, 3, paths);
//children of 1
yield return CreateInvariantKit(20, 1, 1, paths);
yield return CreateInvariantKit(30, 1, 2, paths);
yield return CreateInvariantKit(40, 1, 3, paths);
}
Init(GetKits());
var snapshotService = (PublishedSnapshotService)_snapshotService;
var contentStore = snapshotService.GetContentStore();
Assert.AreEqual(1, contentStore.Test.LiveGen);
Assert.IsTrue(contentStore.Test.NextGen);
var middleNode = contentStore.Test.GetValues(1)[0];
Assert.AreEqual(1, middleNode.gen);
AssertLinkedNode(middleNode.contentNode, 100, 2, 3, 20, 40);
//This will set a flag to force creating a new Gen next time the store is locked (i.e. In Notify)
contentStore.CreateSnapshot();
Assert.IsFalse(contentStore.Test.NextGen);
_snapshotService.Notify(new[]
{
new ContentCacheRefresher.JsonPayload(1, Guid.Empty, TreeChangeTypes.RefreshNode)
}, out _, out _);
Assert.AreEqual(2, contentStore.Test.LiveGen);
Assert.IsTrue(contentStore.Test.NextGen);
middleNode = contentStore.Test.GetValues(1)[0];
Assert.AreEqual(2, middleNode.gen);
AssertLinkedNode(middleNode.contentNode, 100, 2, 3, 20, 40);
}
/// <summary>
/// This addresses issue: https://github.com/umbraco/Umbraco-CMS/issues/6698
/// </summary>
/// <remarks>
/// This test mimics if someone were to:
/// 1) Unpublish a "middle child"
/// 2) Save and publish it
/// 3) Publish it with descendants
/// 4) Repeat steps 2 and 3
///
/// Which has caused an exception. To replicate this test:
/// 1) RefreshBranch with kits for a branch where the top most node is unpublished
/// 2) RefreshBranch with kits for the branch where the top most node is published
/// 3) RefreshBranch with kits for the branch where the top most node is published
/// 4) RefreshNode
/// 5) RefreshBranch with kits for the branch where the top most node is published
/// </remarks>
[Test]
public void Refresh_Branch_With_Alternating_Publish_Flags()
{
// NOTE: these tests are not using real scopes, in which case a Scope does not control
// how the snapshots generations work. We are forcing new snapshot generations manually.
IEnumerable<ContentNodeKit> GetKits()
{
var paths = new Dictionary<int, string> { { -1, "-1" } };
//root
yield return CreateInvariantKit(100, -1, 1, paths);
//site
yield return CreateInvariantKit(2, 100, 1, paths);
yield return CreateInvariantKit(1, 100, 2, paths); //middle child
yield return CreateInvariantKit(3, 100, 3, paths);
//children of 1
yield return CreateInvariantKit(20, 1, 1, paths);
yield return CreateInvariantKit(30, 1, 2, paths);
yield return CreateInvariantKit(40, 1, 3, paths);
}
//init with all published
Init(GetKits());
var snapshotService = (PublishedSnapshotService)_snapshotService;
var contentStore = snapshotService.GetContentStore();
var rootKit = _source.Kits[1].Clone();
void ChangePublishFlagOfRoot(bool published, int assertGen, TreeChangeTypes changeType)
{
//This will set a flag to force creating a new Gen next time the store is locked (i.e. In Notify)
contentStore.CreateSnapshot();
Assert.IsFalse(contentStore.Test.NextGen);
//Change the root publish flag
var kit = rootKit.Clone();
kit.DraftData = published ? null : kit.PublishedData;
kit.PublishedData = published? kit.PublishedData : null;
_source.Kits[1] = kit;
_snapshotService.Notify(new[]
{
new ContentCacheRefresher.JsonPayload(1, Guid.Empty, changeType)
}, out _, out _);
Assert.AreEqual(assertGen, contentStore.Test.LiveGen);
Assert.IsTrue(contentStore.Test.NextGen);
//get the latest gen for content Id 1
var (gen, contentNode) = contentStore.Test.GetValues(1)[0];
Assert.AreEqual(assertGen, gen);
//even when unpublishing/re-publishing/etc... the linked list is always maintained
AssertLinkedNode(contentNode, 100, 2, 3, 20, 40);
}
//unpublish the root
ChangePublishFlagOfRoot(false, 2, TreeChangeTypes.RefreshBranch);
//publish the root (since it's not published, it will cause a RefreshBranch)
ChangePublishFlagOfRoot(true, 3, TreeChangeTypes.RefreshBranch);
//publish root + descendants
ChangePublishFlagOfRoot(true, 4, TreeChangeTypes.RefreshBranch);
//save/publish the root (since it's already published, it will just cause a RefreshNode
ChangePublishFlagOfRoot(true, 5, TreeChangeTypes.RefreshNode);
//publish root + descendants
ChangePublishFlagOfRoot(true, 6, TreeChangeTypes.RefreshBranch);
}
[Test]
public void Refresh_Branch_Ensures_Linked_List()
{

View File

@@ -36,6 +36,12 @@ namespace Umbraco.Tests.PublishedContent
private ContentType _contentType;
private PropertyType _propertyType;
[TearDown]
public void Teardown()
{
_snapshotService?.Dispose();
}
private void Init()
{
Current.Reset();
@@ -303,5 +309,6 @@ namespace Umbraco.Tests.PublishedContent
Assert.IsFalse(c2.IsPublished("dk-DA"));
Assert.IsTrue(c2.IsPublished("de-DE"));
}
}
}

View File

@@ -73,7 +73,7 @@ namespace Umbraco.Tests.Scoping
// xmlStore.Xml - the actual main xml document
// publishedContentCache.GetXml() - the captured xml
private static XmlStore XmlStore => (Current.Factory.GetInstance<IPublishedSnapshotService>() as PublishedSnapshotService).XmlStore;
private static XmlStore XmlStore => (Current.Factory.GetInstance<IPublishedSnapshotService>() as XmlPublishedSnapshotService).XmlStore;
private static XmlDocument XmlMaster => XmlStore.Xml;
private static XmlDocument XmlInContext => ((PublishedContentCache) Umbraco.Web.Composing.Current.UmbracoContext.Content).GetXml(false);

View File

@@ -105,13 +105,26 @@ namespace Umbraco.Tests.Services
}
}
[Test]
public void Change_Content_Type_Variation_Clears_Redirects()
[TestCase(ContentVariation.Nothing, ContentVariation.Nothing, false)]
[TestCase(ContentVariation.Nothing, ContentVariation.Culture, true)]
[TestCase(ContentVariation.Nothing, ContentVariation.CultureAndSegment, true)]
[TestCase(ContentVariation.Nothing, ContentVariation.Segment, true)]
[TestCase(ContentVariation.Culture, ContentVariation.Nothing, true)]
[TestCase(ContentVariation.Culture, ContentVariation.Culture, false)]
[TestCase(ContentVariation.Culture, ContentVariation.Segment, true)]
[TestCase(ContentVariation.Culture, ContentVariation.CultureAndSegment, true)]
[TestCase(ContentVariation.Segment, ContentVariation.Nothing, true)]
[TestCase(ContentVariation.Segment, ContentVariation.Culture, true)]
[TestCase(ContentVariation.Segment, ContentVariation.Segment, false)]
[TestCase(ContentVariation.Segment, ContentVariation.CultureAndSegment, true)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Nothing, true)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Culture, true)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Segment, true)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.CultureAndSegment, false)]
public void Change_Content_Type_Variation_Clears_Redirects(ContentVariation startingContentTypeVariation, ContentVariation changedContentTypeVariation, bool shouldUrlRedirectsBeCleared)
{
var contentType = MockedContentTypes.CreateBasicContentType();
contentType.Variations = ContentVariation.Nothing;
var properties = CreatePropertyCollection(("title", ContentVariation.Nothing));
contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" });
var contentType = MockedContentTypes.CreateBasicContentType();
contentType.Variations = startingContentTypeVariation;
ServiceContext.ContentTypeService.Save(contentType);
var contentType2 = MockedContentTypes.CreateBasicContentType("test");
ServiceContext.ContentTypeService.Save(contentType2);
@@ -119,6 +132,11 @@ namespace Umbraco.Tests.Services
//create some content of this content type
IContent doc = MockedContent.CreateBasicContent(contentType);
doc.Name = "Hello1";
if(startingContentTypeVariation.HasFlag(ContentVariation.Culture))
{
doc.SetCultureName(doc.Name, "en-US");
}
ServiceContext.ContentService.Save(doc);
IContent doc2 = MockedContent.CreateBasicContent(contentType2);
@@ -127,24 +145,27 @@ namespace Umbraco.Tests.Services
ServiceContext.RedirectUrlService.Register("hello/world", doc.Key);
ServiceContext.RedirectUrlService.Register("hello2/world2", doc2.Key);
// These 2 assertions should probably be moved to a test for the Register() method?
Assert.AreEqual(1, ServiceContext.RedirectUrlService.GetContentRedirectUrls(doc.Key).Count());
Assert.AreEqual(1, ServiceContext.RedirectUrlService.GetContentRedirectUrls(doc2.Key).Count());
//change variation
contentType.Variations = ContentVariation.Culture;
contentType.Variations = changedContentTypeVariation;
ServiceContext.ContentTypeService.Save(contentType);
Assert.AreEqual(0, ServiceContext.RedirectUrlService.GetContentRedirectUrls(doc.Key).Count());
var expectedRedirectUrlCount = shouldUrlRedirectsBeCleared ? 0 : 1;
Assert.AreEqual(expectedRedirectUrlCount, ServiceContext.RedirectUrlService.GetContentRedirectUrls(doc.Key).Count());
Assert.AreEqual(1, ServiceContext.RedirectUrlService.GetContentRedirectUrls(doc2.Key).Count());
}
[Test]
public void Change_Content_Type_From_Invariant_Variant()
{
[TestCase(ContentVariation.Nothing, ContentVariation.Culture)]
[TestCase(ContentVariation.Nothing, ContentVariation.CultureAndSegment)]
[TestCase(ContentVariation.Segment, ContentVariation.Culture)]
[TestCase(ContentVariation.Segment, ContentVariation.CultureAndSegment)]
public void Change_Content_Type_From_No_Culture_To_Culture(ContentVariation from, ContentVariation to)
{
var contentType = MockedContentTypes.CreateBasicContentType();
contentType.Variations = ContentVariation.Nothing;
var properties = CreatePropertyCollection(("title", ContentVariation.Nothing));
contentType.Variations = from;
var properties = CreatePropertyCollection(("title", from));
contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" });
ServiceContext.ContentTypeService.Save(contentType);
@@ -159,12 +180,12 @@ namespace Umbraco.Tests.Services
Assert.AreEqual("Hello1", doc.Name);
Assert.AreEqual("hello world", doc.GetValue("title"));
Assert.IsTrue(doc.Edited);
Assert.IsFalse (doc.IsCultureEdited("en-US"));
Assert.IsFalse(doc.IsCultureEdited("en-US"));
//change the content type to be variant, we will also update the name here to detect the copy changes
doc.Name = "Hello2";
ServiceContext.ContentService.Save(doc);
contentType.Variations = ContentVariation.Culture;
contentType.Variations = to;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
@@ -176,7 +197,7 @@ namespace Umbraco.Tests.Services
//change back property type to be invariant, we will also update the name here to detect the copy changes
doc.SetCultureName("Hello3", "en-US");
ServiceContext.ContentService.Save(doc);
contentType.Variations = ContentVariation.Nothing;
contentType.Variations = from;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
@@ -186,12 +207,15 @@ namespace Umbraco.Tests.Services
Assert.IsFalse(doc.IsCultureEdited("en-US"));
}
[Test]
public void Change_Content_Type_From_Variant_Invariant()
[TestCase(ContentVariation.Culture, ContentVariation.Nothing)]
[TestCase(ContentVariation.Culture, ContentVariation.Segment)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Nothing)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Segment)]
public void Change_Content_Type_From_Culture_To_No_Culture(ContentVariation startingContentTypeVariation, ContentVariation changeContentTypeVariationTo)
{
var contentType = MockedContentTypes.CreateBasicContentType();
contentType.Variations = ContentVariation.Culture;
var properties = CreatePropertyCollection(("title", ContentVariation.Culture));
contentType.Variations = startingContentTypeVariation;
var properties = CreatePropertyCollection(("title", startingContentTypeVariation));
contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" });
ServiceContext.ContentTypeService.Save(contentType);
@@ -210,7 +234,7 @@ namespace Umbraco.Tests.Services
//change the content type to be invariant, we will also update the name here to detect the copy changes
doc.SetCultureName("Hello2", "en-US");
ServiceContext.ContentService.Save(doc);
contentType.Variations = ContentVariation.Nothing;
contentType.Variations = changeContentTypeVariationTo;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
@@ -222,19 +246,20 @@ namespace Umbraco.Tests.Services
//change back property type to be variant, we will also update the name here to detect the copy changes
doc.Name = "Hello3";
ServiceContext.ContentService.Save(doc);
contentType.Variations = ContentVariation.Culture;
contentType.Variations = startingContentTypeVariation;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
//at this stage all property types were switched to invariant so even though the variant value
//exists it will not be returned because the property type is invariant,
//so this check proves that null will be returned
Assert.AreEqual("Hello3", doc.Name);
Assert.IsNull(doc.GetValue("title", "en-US"));
Assert.IsTrue(doc.Edited);
Assert.IsTrue(doc.IsCultureEdited("en-US")); // this is true because the name change is copied to the default language
//we can now switch the property type to be variant and the value can be returned again
contentType.PropertyTypes.First().Variations = ContentVariation.Culture;
contentType.PropertyTypes.First().Variations = startingContentTypeVariation;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
@@ -242,32 +267,129 @@ namespace Umbraco.Tests.Services
Assert.AreEqual("hello world", doc.GetValue("title", "en-US"));
Assert.IsTrue(doc.Edited);
Assert.IsTrue(doc.IsCultureEdited("en-US"));
}
[Test]
public void Change_Property_Type_From_To_Variant_On_Invariant_Content_Type()
[TestCase(ContentVariation.Nothing, ContentVariation.Nothing)]
[TestCase(ContentVariation.Nothing, ContentVariation.Culture)]
[TestCase(ContentVariation.Nothing, ContentVariation.Segment)]
[TestCase(ContentVariation.Nothing, ContentVariation.CultureAndSegment)]
[TestCase(ContentVariation.Culture, ContentVariation.Nothing)]
[TestCase(ContentVariation.Culture, ContentVariation.Culture)]
[TestCase(ContentVariation.Culture, ContentVariation.Segment)]
[TestCase(ContentVariation.Culture, ContentVariation.CultureAndSegment)]
[TestCase(ContentVariation.Segment, ContentVariation.Nothing)]
[TestCase(ContentVariation.Segment, ContentVariation.Culture)]
[TestCase(ContentVariation.Segment, ContentVariation.Segment)]
[TestCase(ContentVariation.Segment, ContentVariation.CultureAndSegment)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Nothing)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Culture)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Segment)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.CultureAndSegment)]
public void Preserve_Content_Name_After_Content_Type_Variation_Change(ContentVariation contentTypeVariationFrom, ContentVariation contentTypeVariationTo)
{
var contentType = MockedContentTypes.CreateBasicContentType();
contentType.Variations = ContentVariation.Nothing;
var properties = CreatePropertyCollection(("title", ContentVariation.Nothing));
contentType.Variations = contentTypeVariationFrom;
ServiceContext.ContentTypeService.Save(contentType);
var invariantContentName = "Content Invariant";
var defaultCultureContentName = "Content en-US";
var defaultCulture = "en-US";
var nlContentName = "Content nl-NL";
var nlCulture = "nl-NL";
ServiceContext.LocalizationService.Save(new Language(nlCulture));
var includeCultureNames = contentType.Variations.HasFlag(ContentVariation.Culture);
// Create some content of this content type
IContent doc = MockedContent.CreateBasicContent(contentType);
doc.Name = invariantContentName;
if (includeCultureNames)
{
Assert.DoesNotThrow(() => doc.SetCultureName(defaultCultureContentName, defaultCulture));
Assert.DoesNotThrow(() => doc.SetCultureName(nlContentName, nlCulture));
} else
{
Assert.Throws<NotSupportedException>(() => doc.SetCultureName(defaultCultureContentName, defaultCulture));
Assert.Throws<NotSupportedException>(() => doc.SetCultureName(nlContentName, nlCulture));
}
ServiceContext.ContentService.Save(doc);
doc = ServiceContext.ContentService.GetById(doc.Id);
AssertAll();
// Change variation
contentType.Variations = contentTypeVariationTo;
ServiceContext.ContentService.Save(doc);
doc = ServiceContext.ContentService.GetById(doc.Id);
AssertAll();
void AssertAll()
{
if (includeCultureNames)
{
// Invariant content name is not preserved when content type is set to culture
Assert.AreEqual(defaultCultureContentName, doc.Name);
Assert.AreEqual(doc.Name, doc.GetCultureName(defaultCulture));
Assert.AreEqual(nlContentName, doc.GetCultureName(nlCulture));
}
else
{
Assert.AreEqual(invariantContentName, doc.Name);
Assert.AreEqual(null, doc.GetCultureName(defaultCulture));
Assert.AreEqual(null, doc.GetCultureName(nlCulture));
}
}
}
[TestCase(ContentVariation.Nothing, ContentVariation.Nothing)]
[TestCase(ContentVariation.Nothing, ContentVariation.Culture)]
[TestCase(ContentVariation.Nothing, ContentVariation.Segment)]
[TestCase(ContentVariation.Nothing, ContentVariation.CultureAndSegment)]
[TestCase(ContentVariation.Culture, ContentVariation.Nothing)]
[TestCase(ContentVariation.Culture, ContentVariation.Culture)]
[TestCase(ContentVariation.Culture, ContentVariation.Segment)]
[TestCase(ContentVariation.Culture, ContentVariation.CultureAndSegment)]
[TestCase(ContentVariation.Segment, ContentVariation.Nothing)]
[TestCase(ContentVariation.Segment, ContentVariation.Culture)]
[TestCase(ContentVariation.Segment, ContentVariation.Segment)]
[TestCase(ContentVariation.Segment, ContentVariation.CultureAndSegment)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Nothing)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Culture)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Segment)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.CultureAndSegment)]
public void Verify_If_Property_Type_Variation_Is_Correctly_Corrected_When_Content_Type_Is_Updated(ContentVariation contentTypeVariation, ContentVariation propertyTypeVariation)
{
var contentType = MockedContentTypes.CreateBasicContentType();
// We test an updated content type so it has to be saved first.
ServiceContext.ContentTypeService.Save(contentType);
// Update it
contentType.Variations = contentTypeVariation;
var properties = CreatePropertyCollection(("title", propertyTypeVariation));
contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" });
ServiceContext.ContentTypeService.Save(contentType);
//change the property type to be variant
contentType.PropertyTypes.First().Variations = ContentVariation.Culture;
//Cannot change a property type to be variant if the content type itself is not variant
Assert.Throws<InvalidOperationException>(() => ServiceContext.ContentTypeService.Save(contentType));
// Check if property type variations have been updated correctly
Assert.AreEqual(properties.First().Variations, contentTypeVariation & propertyTypeVariation);
}
[Test]
public void Change_Property_Type_From_Invariant_Variant()
[TestCase(ContentVariation.Nothing, ContentVariation.Culture)]
[TestCase(ContentVariation.Nothing, ContentVariation.CultureAndSegment)]
[TestCase(ContentVariation.Segment, ContentVariation.Culture)]
[TestCase(ContentVariation.Segment, ContentVariation.CultureAndSegment)]
public void Change_Property_Type_From_Invariant_Variant(ContentVariation invariant, ContentVariation variant)
{
var contentType = MockedContentTypes.CreateBasicContentType();
contentType.Variations = ContentVariation.Culture;
var properties = CreatePropertyCollection(("title", ContentVariation.Nothing));
// content type supports all variations
contentType.Variations = ContentVariation.Culture | ContentVariation.Segment;
var properties = CreatePropertyCollection(("title", invariant));
contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" });
ServiceContext.ContentTypeService.Save(contentType);
@@ -283,7 +405,7 @@ namespace Umbraco.Tests.Services
Assert.IsTrue(doc.Edited);
//change the property type to be variant
contentType.PropertyTypes.First().Variations = ContentVariation.Culture;
contentType.PropertyTypes.First().Variations = variant;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
@@ -292,7 +414,7 @@ namespace Umbraco.Tests.Services
Assert.IsTrue(doc.Edited);
//change back property type to be invariant
contentType.PropertyTypes.First().Variations = ContentVariation.Nothing;
contentType.PropertyTypes.First().Variations = invariant;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
@@ -301,13 +423,17 @@ namespace Umbraco.Tests.Services
Assert.IsTrue(doc.Edited);
}
[Test]
public void Change_Property_Type_From_Variant_Invariant()
[TestCase(ContentVariation.Culture, ContentVariation.Nothing)]
[TestCase(ContentVariation.Culture, ContentVariation.Segment)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Nothing)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Segment)]
public void Change_Property_Type_From_Variant_Invariant(ContentVariation variant, ContentVariation invariant)
{
//create content type with a property type that varies by culture
var contentType = MockedContentTypes.CreateBasicContentType();
contentType.Variations = ContentVariation.Culture;
var properties = CreatePropertyCollection(("title", ContentVariation.Culture));
// content type supports all variations
contentType.Variations = ContentVariation.Culture | ContentVariation.Segment;
var properties = CreatePropertyCollection(("title", variant));
contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" });
ServiceContext.ContentTypeService.Save(contentType);
@@ -320,33 +446,37 @@ namespace Umbraco.Tests.Services
Assert.AreEqual("hello world", doc.GetValue("title", "en-US"));
//change the property type to be invariant
contentType.PropertyTypes.First().Variations = ContentVariation.Nothing;
contentType.PropertyTypes.First().Variations = invariant;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
Assert.AreEqual("hello world", doc.GetValue("title"));
//change back property type to be variant
contentType.PropertyTypes.First().Variations = ContentVariation.Culture;
contentType.PropertyTypes.First().Variations = variant;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
Assert.AreEqual("hello world", doc.GetValue("title", "en-US"));
}
[Test]
public void Change_Property_Type_From_Variant_Invariant_On_A_Composition()
[TestCase(ContentVariation.Culture, ContentVariation.Nothing)]
[TestCase(ContentVariation.Culture, ContentVariation.Segment)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Nothing)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Segment)]
public void Change_Property_Type_From_Variant_Invariant_On_A_Composition(ContentVariation variant, ContentVariation invariant)
{
//create content type with a property type that varies by culture
var contentType = MockedContentTypes.CreateBasicContentType();
contentType.Variations = ContentVariation.Culture;
var properties = CreatePropertyCollection(("title", ContentVariation.Culture));
// content type supports all variations
contentType.Variations = ContentVariation.Culture | ContentVariation.Segment;
var properties = CreatePropertyCollection(("title", variant));
contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" });
ServiceContext.ContentTypeService.Save(contentType);
//compose this from the other one
var contentType2 = MockedContentTypes.CreateBasicContentType("test");
contentType2.Variations = ContentVariation.Culture;
contentType2.Variations = contentType.Variations;
contentType2.AddContentType(contentType);
ServiceContext.ContentTypeService.Save(contentType2);
@@ -362,7 +492,7 @@ namespace Umbraco.Tests.Services
ServiceContext.ContentService.Save(doc2);
//change the property type to be invariant
contentType.PropertyTypes.First().Variations = ContentVariation.Nothing;
contentType.PropertyTypes.First().Variations = invariant;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
doc2 = ServiceContext.ContentService.GetById(doc2.Id); //re-get
@@ -371,7 +501,7 @@ namespace Umbraco.Tests.Services
Assert.AreEqual("hello world", doc2.GetValue("title"));
//change back property type to be variant
contentType.PropertyTypes.First().Variations = ContentVariation.Culture;
contentType.PropertyTypes.First().Variations = variant;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
doc2 = ServiceContext.ContentService.GetById(doc2.Id); //re-get
@@ -380,19 +510,22 @@ namespace Umbraco.Tests.Services
Assert.AreEqual("hello world", doc2.GetValue("title", "en-US"));
}
[Test]
public void Change_Content_Type_From_Variant_Invariant_On_A_Composition()
[TestCase(ContentVariation.Culture, ContentVariation.Nothing)]
[TestCase(ContentVariation.Culture, ContentVariation.Segment)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Nothing)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Segment)]
public void Change_Content_Type_From_Variant_Invariant_On_A_Composition(ContentVariation variant, ContentVariation invariant)
{
//create content type with a property type that varies by culture
var contentType = MockedContentTypes.CreateBasicContentType();
contentType.Variations = ContentVariation.Culture;
contentType.Variations = variant;
var properties = CreatePropertyCollection(("title", ContentVariation.Culture));
contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" });
ServiceContext.ContentTypeService.Save(contentType);
//compose this from the other one
var contentType2 = MockedContentTypes.CreateBasicContentType("test");
contentType2.Variations = ContentVariation.Culture;
contentType2.Variations = contentType.Variations;
contentType2.AddContentType(contentType);
ServiceContext.ContentTypeService.Save(contentType2);
@@ -408,7 +541,7 @@ namespace Umbraco.Tests.Services
ServiceContext.ContentService.Save(doc2);
//change the content type to be invariant
contentType.Variations = ContentVariation.Nothing;
contentType.Variations = invariant;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
doc2 = ServiceContext.ContentService.GetById(doc2.Id); //re-get
@@ -417,7 +550,7 @@ namespace Umbraco.Tests.Services
Assert.AreEqual("hello world", doc2.GetValue("title"));
//change back content type to be variant
contentType.Variations = ContentVariation.Culture;
contentType.Variations = variant;
ServiceContext.ContentTypeService.Save(contentType);
doc = ServiceContext.ContentService.GetById(doc.Id); //re-get
doc2 = ServiceContext.ContentService.GetById(doc2.Id); //re-get
@@ -693,22 +826,25 @@ namespace Umbraco.Tests.Services
"{'properties':{'value1':[{'culture':'en','seg':'','val':'v1en'},{'culture':'fr','seg':'','val':'v1fr'}],'value2':[{'culture':'en','seg':'','val':'v2'}]},'cultureData':");
}
[Test]
public void Change_Property_Variations_From_Variant_To_Invariant_And_Ensure_Edited_Values_Are_Renormalized()
[TestCase(ContentVariation.Culture, ContentVariation.Nothing)]
[TestCase(ContentVariation.Culture, ContentVariation.Segment)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Nothing)]
[TestCase(ContentVariation.CultureAndSegment, ContentVariation.Segment)]
public void Change_Property_Variations_From_Variant_To_Invariant_And_Ensure_Edited_Values_Are_Renormalized(ContentVariation variant, ContentVariation invariant)
{
// one simple content type, variant, with both variant and invariant properties
// can change an invariant property to variant and back
CreateFrenchAndEnglishLangs();
var contentType = CreateContentType(ContentVariation.Culture);
var contentType = CreateContentType(ContentVariation.Culture | ContentVariation.Segment);
var properties = CreatePropertyCollection(("value1", ContentVariation.Culture));
var properties = CreatePropertyCollection(("value1", variant));
contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" });
ServiceContext.ContentTypeService.Save(contentType);
var document = (IContent)new Content("document", -1, contentType);
IContent document = new Content("document", -1, contentType);
document.SetCultureName("doc1en", "en");
document.SetCultureName("doc1fr", "fr");
document.SetValue("value1", "v1en-init", "en");
@@ -737,7 +873,7 @@ namespace Umbraco.Tests.Services
Assert.IsTrue(document.Edited);
// switch property type to Invariant
contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = ContentVariation.Nothing;
contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = invariant;
ServiceContext.ContentTypeService.Save(contentType); //This is going to have to re-normalize the "Edited" flag
document = ServiceContext.ContentService.GetById(document.Id);
@@ -764,7 +900,7 @@ namespace Umbraco.Tests.Services
Assert.IsFalse(document.Edited);
// switch property back to Culture
contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = ContentVariation.Culture;
contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = variant;
ServiceContext.ContentTypeService.Save(contentType);
document = ServiceContext.ContentService.GetById(document.Id);
@@ -793,17 +929,20 @@ namespace Umbraco.Tests.Services
Assert.IsFalse(document.Edited);
}
[Test]
public void Change_Property_Variations_From_Invariant_To_Variant_And_Ensure_Edited_Values_Are_Renormalized()
[TestCase(ContentVariation.Nothing, ContentVariation.Culture)]
[TestCase(ContentVariation.Nothing, ContentVariation.CultureAndSegment)]
[TestCase(ContentVariation.Segment, ContentVariation.Culture)]
[TestCase(ContentVariation.Segment, ContentVariation.CultureAndSegment)]
public void Change_Property_Variations_From_Invariant_To_Variant_And_Ensure_Edited_Values_Are_Renormalized(ContentVariation invariant, ContentVariation variant)
{
// one simple content type, variant, with both variant and invariant properties
// can change an invariant property to variant and back
CreateFrenchAndEnglishLangs();
var contentType = CreateContentType(ContentVariation.Culture);
var contentType = CreateContentType(ContentVariation.Culture | ContentVariation.Segment);
var properties = CreatePropertyCollection(("value1", ContentVariation.Nothing));
var properties = CreatePropertyCollection(("value1", invariant));
contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" });
ServiceContext.ContentTypeService.Save(contentType);
@@ -833,7 +972,7 @@ namespace Umbraco.Tests.Services
Assert.IsTrue(document.Edited);
// switch property type to Culture
contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = ContentVariation.Culture;
contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = variant;
ServiceContext.ContentTypeService.Save(contentType); //This is going to have to re-normalize the "Edited" flag
document = ServiceContext.ContentService.GetById(document.Id);
@@ -858,7 +997,7 @@ namespace Umbraco.Tests.Services
Assert.IsFalse(document.Edited);
// switch property back to Invariant
contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = ContentVariation.Nothing;
contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = invariant;
ServiceContext.ContentTypeService.Save(contentType);
document = ServiceContext.ContentService.GetById(document.Id);

View File

@@ -96,8 +96,7 @@ namespace Umbraco.Tests.Services
var properties = pmember.Properties.ToList();
for (var i = 0; i < aliases.Length; i++)
Assert.AreEqual(properties[i].Alias, aliases[i]);
Assert.IsTrue(properties.Select(x => x.Alias).ContainsAll(aliases));
var email = properties[aliases.IndexOf("Email")];
Assert.AreEqual("xemail", email.GetSourceValue());

View File

@@ -865,7 +865,7 @@ namespace Umbraco.Tests.Services
var userService = ServiceContext.UserService;
// Act & Assert
Assert.Throws<ArgumentNullOrEmptyException>(() => userService.CreateUserWithIdentity(string.Empty, "john@umbraco.io"));
Assert.Throws<ArgumentException>(() => userService.CreateUserWithIdentity(string.Empty, "john@umbraco.io"));
}
[Test]

View File

@@ -329,6 +329,11 @@ namespace Umbraco.Tests.TestHelpers
{
throw new NotImplementedException();
}
public IReadOnlyDictionary<Udi, IEnumerable<string>> GetReferences(int id)
{
throw new NotImplementedException();
}
}
#endregion

View File

@@ -259,7 +259,7 @@ namespace Umbraco.Tests.TestHelpers
var publishedSnapshotAccessor = new UmbracoContextPublishedSnapshotAccessor(Umbraco.Web.Composing.Current.UmbracoContextAccessor);
var variationContextAccessor = new TestVariationContextAccessor();
var service = new PublishedSnapshotService(
var service = new XmlPublishedSnapshotService(
ServiceContext,
Factory.GetInstance<IPublishedContentTypeFactory>(),
ScopeProvider,
@@ -357,14 +357,14 @@ namespace Umbraco.Tests.TestHelpers
protected UmbracoContext GetUmbracoContext(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable<IUrlProvider> urlProviders = null, IEnumerable<IMediaUrlProvider> mediaUrlProviders = null, IGlobalSettings globalSettings = null, IPublishedSnapshotService snapshotService = null)
{
// ensure we have a PublishedCachesService
var service = snapshotService ?? PublishedSnapshotService as PublishedSnapshotService;
var service = snapshotService ?? PublishedSnapshotService as XmlPublishedSnapshotService;
if (service == null)
throw new Exception("Not a proper XmlPublishedCache.PublishedCachesService.");
if (service is PublishedSnapshotService)
if (service is XmlPublishedSnapshotService)
{
// re-initialize PublishedCacheService content with an Xml source with proper template id
((PublishedSnapshotService)service).XmlStore.GetXmlDocument = () =>
((XmlPublishedSnapshotService)service).XmlStore.GetXmlDocument = () =>
{
var doc = new XmlDocument();
doc.LoadXml(GetXmlContent(templateId));

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
@@ -8,6 +9,8 @@ namespace Umbraco.Tests.Testing
{
public abstract class TestOptionAttributeBase : Attribute
{
public static readonly List<Assembly> ScanAssemblies = new List<Assembly>();
public static TOptions GetTestOptions<TOptions>(MethodInfo method)
where TOptions : TestOptionAttributeBase, new()
{
@@ -28,9 +31,18 @@ namespace Umbraco.Tests.Testing
var test = TestContext.CurrentContext.Test;
var typeName = test.ClassName;
var methodName = test.MethodName;
var type = Type.GetType(typeName, true);
var type = Type.GetType(typeName, false);
if (type == null)
throw new PanicException($"Could not resolve the type from type name {typeName}"); // makes no sense
{
type = ScanAssemblies
.Select(assembly => assembly.GetType(typeName, false))
.FirstOrDefault(x => x != null);
if (type == null)
{
throw new PanicException($"Could not resolve the running test fixture from type name {typeName}.\n" +
$"To use base classes from Umbraco.Tests, add your test assembly to TestOptionAttributeBase.ScanAssemblies");
}
}
var methodInfo = type.GetMethod(methodName); // what about overloads?
var options = GetTestOptions<TOptions>(methodInfo);
return options;

View File

@@ -7,10 +7,13 @@ using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Logging;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Persistence;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Stubs;
@@ -19,6 +22,7 @@ using Umbraco.Web;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
using Umbraco.Web.WebApi;
using Current = Umbraco.Web.Composing.Current;
namespace Umbraco.Tests.Testing.TestingTests
@@ -88,5 +92,26 @@ namespace Umbraco.Tests.Testing.TestingTests
Assert.AreEqual("/hello/world/1234", theUrlProvider.GetUrl(publishedContent));
}
[Test]
public void Can_Mock_UmbracoApiController_Dependencies_With_Injected_UmbracoMapper()
{
var umbracoContext = TestObjects.GetUmbracoContextMock();
var membershipHelper = new MembershipHelper(umbracoContext.HttpContext, Mock.Of<IPublishedMemberCache>(), Mock.Of<MembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IUserService>(), Mock.Of<IPublicAccessService>(), Mock.Of<AppCaches>(), Mock.Of<ILogger>());
var umbracoHelper = new UmbracoHelper(Mock.Of<IPublishedContent>(), Mock.Of<ITagQuery>(), Mock.Of<ICultureDictionaryFactory>(), Mock.Of<IUmbracoComponentRenderer>(), Mock.Of<IPublishedContentQuery>(), membershipHelper);
var umbracoMapper = new UmbracoMapper(new MapDefinitionCollection(new[] { Mock.Of<IMapDefinition>() }));
// ReSharper disable once UnusedVariable
var umbracoApiController = new FakeUmbracoApiController(Mock.Of<IGlobalSettings>(), Mock.Of<IUmbracoContextAccessor>(), Mock.Of<ISqlContext>(), ServiceContext.CreatePartial(), AppCaches.NoCache, Mock.Of<IProfilingLogger>(), Mock.Of<IRuntimeState>(), umbracoHelper, umbracoMapper);
Assert.Pass();
}
}
internal class FakeUmbracoApiController : UmbracoApiController
{
public FakeUmbracoApiController(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper) { }
public FakeUmbracoApiController(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper, UmbracoMapper umbracoMapper) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper, umbracoMapper) { }
}
}

View File

@@ -79,7 +79,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Castle.Core" Version="4.3.1" />
<PackageReference Include="Examine" Version="1.0.0" />
<PackageReference Include="Examine" Version="1.0.1" />
<PackageReference Include="HtmlAgilityPack">
<Version>1.8.14</Version>
</PackageReference>
@@ -511,7 +511,7 @@
<Compile Include="LegacyXmlPublishedCache\PublishedMediaCache.cs" />
<Compile Include="LegacyXmlPublishedCache\PublishedMemberCache.cs" />
<Compile Include="LegacyXmlPublishedCache\PublishedSnapshot.cs" />
<Compile Include="LegacyXmlPublishedCache\PublishedSnapshotService.cs" />
<Compile Include="LegacyXmlPublishedCache\XmlPublishedSnapshotService.cs" />
<Compile Include="LegacyXmlPublishedCache\RoutesCache.cs" />
<Compile Include="LegacyXmlPublishedCache\SafeXmlReaderWriter.cs" />
<Compile Include="LegacyXmlPublishedCache\UmbracoContextCache.cs" />

View File

@@ -7,6 +7,7 @@ using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Store;
using Moq;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
@@ -44,11 +45,10 @@ namespace Umbraco.Tests.UmbracoExamine
public static MediaIndexPopulator GetMediaIndexRebuilder(PropertyEditorCollection propertyEditors, IMediaService mediaService)
{
var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService());
var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService(), GetMockLogger());
var mediaIndexDataSource = new MediaIndexPopulator(null, mediaService, mediaValueSetBuilder);
return mediaIndexDataSource;
}
public static IContentService GetMockContentService()
{
long longTotalRecs;
@@ -146,6 +146,11 @@ namespace Umbraco.Tests.UmbracoExamine
return mediaTypeServiceMock.Object;
}
public static IProfilingLogger GetMockLogger()
{
return new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>());
}
public static UmbracoContentIndex GetUmbracoIndexer(
IProfilingLogger profilingLogger,
Directory luceneDir,

View File

@@ -29,7 +29,7 @@ namespace Umbraco.Tests.Web.Mvc
[UmbracoTest(WithApplication = true)]
public class UmbracoViewPageTests : UmbracoTestBase
{
private PublishedSnapshotService _service;
private XmlPublishedSnapshotService _service;
[TearDown]
public override void TearDown()
@@ -421,7 +421,7 @@ namespace Umbraco.Tests.Web.Mvc
var scopeProvider = TestObjects.GetScopeProvider(Mock.Of<ILogger>());
var factory = Mock.Of<IPublishedContentTypeFactory>();
var umbracoContextAccessor = Mock.Of<IUmbracoContextAccessor>();
_service = new PublishedSnapshotService(svcCtx, factory, scopeProvider, cache,
_service = new XmlPublishedSnapshotService(svcCtx, factory, scopeProvider, cache,
null, null,
umbracoContextAccessor, null, null, null,
new TestDefaultCultureAccessor(),