diff --git a/.gitignore b/.gitignore index 8fb2789eea..dc6f431550 100644 --- a/.gitignore +++ b/.gitignore @@ -189,3 +189,9 @@ cypress.env.json /src/Umbraco.Web.UI.NetCore/App_Data/TEMP/* /src/Umbraco.Web.UI.NetCore/App_Data/Smidge/Cache/* /src/Umbraco.Web.UI.NetCore/umbraco/logs + +src/Umbraco.Tests.Integration/umbraco/logs/ + +src/Umbraco.Tests.Integration/Views/ + +src/Umbraco.Tests/TEMP/ diff --git a/src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs b/src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs index bb55762826..4b8098e19d 100644 --- a/src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs +++ b/src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs @@ -41,7 +41,7 @@ namespace Umbraco.Core.Cache public virtual IEnumerable SearchByKey(string keyStartsWith) { var plen = CacheItemPrefix.Length + 1; - IEnumerable entries; + IEnumerable> entries; try { EnterReadLock(); @@ -65,7 +65,7 @@ namespace Umbraco.Core.Cache const string prefix = CacheItemPrefix + "-"; var compiled = new Regex(regex, RegexOptions.Compiled); var plen = prefix.Length; - IEnumerable entries; + IEnumerable> entries; try { EnterReadLock(); @@ -249,7 +249,7 @@ namespace Umbraco.Core.Cache // manipulate the underlying cache entries // these *must* be called from within the appropriate locks // and use the full prefixed cache keys - protected abstract IEnumerable GetDictionaryEntries(); + protected abstract IEnumerable> GetDictionaryEntries(); protected abstract void RemoveEntry(string key); protected abstract object GetEntry(string key); diff --git a/src/Umbraco.Core/Cache/GenericDictionaryRequestAppCache.cs b/src/Umbraco.Core/Cache/GenericDictionaryRequestAppCache.cs index 193235ca7e..31914eb5b0 100644 --- a/src/Umbraco.Core/Cache/GenericDictionaryRequestAppCache.cs +++ b/src/Umbraco.Core/Cache/GenericDictionaryRequestAppCache.cs @@ -115,13 +115,13 @@ namespace Umbraco.Core.Cache #region Entries - protected override IEnumerable GetDictionaryEntries() + protected override IEnumerable> GetDictionaryEntries() { const string prefix = CacheItemPrefix + "-"; - if (!TryGetContextItems(out var items)) return Enumerable.Empty(); + if (!TryGetContextItems(out var items)) return Enumerable.Empty>(); - return items.Cast() + return items.Cast>() .Where(x => x.Key is string s && s.StartsWith(prefix)); } diff --git a/src/Umbraco.Core/Cache/HttpRequestAppCache.cs b/src/Umbraco.Core/Cache/HttpRequestAppCache.cs index 6ce43a7bc9..00d427c965 100644 --- a/src/Umbraco.Core/Cache/HttpRequestAppCache.cs +++ b/src/Umbraco.Core/Cache/HttpRequestAppCache.cs @@ -3,7 +3,6 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Threading; -using Umbraco.Core.Composing; namespace Umbraco.Core.Cache { @@ -17,19 +16,23 @@ namespace Umbraco.Core.Cache /// public class HttpRequestAppCache : FastDictionaryAppCacheBase, IRequestCache { + private static object _syncRoot = new object(); // Using this for locking as the SyncRoot property is not available to us + // on the provided collection provided from .NET Core's HttpContext.Items dictionary, + // as it doesn't implement ICollection where SyncRoot is defined. + /// /// Initializes a new instance of the class with a context, for unit tests! /// - public HttpRequestAppCache(Func requestItems) : base() + public HttpRequestAppCache(Func> requestItems) : base() { ContextItems = requestItems; } - private Func ContextItems { get; } + private Func> ContextItems { get; } public bool IsAvailable => TryGetContextItems(out _); - private bool TryGetContextItems(out IDictionary items) + private bool TryGetContextItems(out IDictionary items) { items = ContextItems?.Invoke(); return items != null; @@ -115,13 +118,13 @@ namespace Umbraco.Core.Cache #region Entries - protected override IEnumerable GetDictionaryEntries() + protected override IEnumerable> GetDictionaryEntries() { const string prefix = CacheItemPrefix + "-"; - if (!TryGetContextItems(out var items)) return Enumerable.Empty(); + if (!TryGetContextItems(out var items)) return Enumerable.Empty>(); - return items.Cast() + return items.Cast>() .Where(x => x.Key is string s && s.StartsWith(prefix)); } @@ -154,7 +157,7 @@ namespace Umbraco.Core.Cache // ContextItems - which is locked, so this should be safe var entered = false; - Monitor.Enter(items.SyncRoot, ref entered); + Monitor.Enter(_syncRoot, ref entered); items[ContextItemsLockKey] = entered; } @@ -166,7 +169,7 @@ namespace Umbraco.Core.Cache var entered = (bool?)items[ContextItemsLockKey] ?? false; if (entered) - Monitor.Exit(items.SyncRoot); + Monitor.Exit(_syncRoot); items.Remove(ContextItemsLockKey); } @@ -179,7 +182,7 @@ namespace Umbraco.Core.Cache yield break; } - foreach (DictionaryEntry item in items) + foreach (var item in items) { yield return new KeyValuePair(item.Key.ToString(), item.Value); } diff --git a/src/Umbraco.Core/Composing/Composition.cs b/src/Umbraco.Core/Composing/Composition.cs index 998f42a2dc..4ebc8c8f7e 100644 --- a/src/Umbraco.Core/Composing/Composition.cs +++ b/src/Umbraco.Core/Composing/Composition.cs @@ -64,10 +64,7 @@ namespace Umbraco.Core.Composing #endregion #region IRegister - - /// - public object Concrete => _register.Concrete; - + /// public void Register(Type serviceType, Lifetime lifetime = Lifetime.Transient) => _register.Register(serviceType, lifetime); @@ -85,33 +82,6 @@ namespace Umbraco.Core.Composing public void Register(Type serviceType, object instance) => _register.Register(serviceType, instance); - /// - public void RegisterFor(Lifetime lifetime = Lifetime.Transient) - where TService : class - => _register.RegisterFor(lifetime); - - /// - public void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient) - where TService : class - => _register.RegisterFor(implementingType, lifetime); - - /// - public void RegisterFor(Func factory, Lifetime lifetime = Lifetime.Transient) - where TService : class - => _register.RegisterFor(factory, lifetime); - - /// - public void RegisterFor(TService instance) - where TService : class - => _register.RegisterFor(instance); - - /// - public void RegisterAuto(Type serviceBaseType) - => _register.RegisterAuto(serviceBaseType); - - /// - public void ConfigureForWeb() - => _register.ConfigureForWeb(); /// public IFactory CreateFactory() @@ -127,13 +97,7 @@ namespace Umbraco.Core.Composing builder.RegisterWith(_register); _builders.Clear(); // no point keep them around - IFactory factory = null; - - // ReSharper disable once AccessToModifiedClosure -- on purpose - _register.Register(_ => factory, Lifetime.Singleton); - factory = _register.CreateFactory(); - - return factory; + return _register.CreateFactory(); } /// @@ -186,38 +150,6 @@ namespace Umbraco.Core.Composing public void RegisterUnique(Type serviceType, object instance) => _uniques[GetUniqueName(serviceType)] = register => register.Register(serviceType, instance); - /// - /// Registers a unique service for a target, as its own implementation. - /// - /// Unique services have one single implementation, and a Singleton lifetime. - public void RegisterUniqueFor() - where TService : class - => _uniques[GetUniqueName()] = register => register.RegisterFor(Lifetime.Singleton); - - /// - /// Registers a unique service for a target, with an implementing type. - /// - /// Unique services have one single implementation, and a Singleton lifetime. - public void RegisterUniqueFor(Type implementingType) - where TService : class - => _uniques[GetUniqueName()] = register => register.RegisterFor(implementingType, Lifetime.Singleton); - - /// - /// Registers a unique service for a target, with an implementation factory. - /// - /// Unique services have one single implementation, and a Singleton lifetime. - public void RegisterUniqueFor(Func factory) - where TService : class - => _uniques[GetUniqueName()] = register => register.RegisterFor(factory, Lifetime.Singleton); - - /// - /// Registers a unique service for a target, with an implementing instance. - /// - /// Unique services have one single implementation, and a Singleton lifetime. - public void RegisterUniqueFor(TService instance) - where TService : class - => _uniques[GetUniqueName()] = register => register.RegisterFor(instance); - #endregion #region Collection Builders diff --git a/src/Umbraco.Core/Composing/IFactory.cs b/src/Umbraco.Core/Composing/IFactory.cs index 768b9207a3..c53e523967 100644 --- a/src/Umbraco.Core/Composing/IFactory.cs +++ b/src/Umbraco.Core/Composing/IFactory.cs @@ -21,15 +21,6 @@ namespace Umbraco.Core.Composing /// Throws an exception if the container failed to get an instance of the specified type. object GetInstance(Type type); - /// - /// Gets a targeted instance of a service. - /// - /// The type of the service. - /// The type of the target. - /// The instance of the specified type for the specified target. - /// Throws an exception if the container failed to get an instance of the specified type. - TService GetInstanceFor(); - /// /// Tries to get an instance of a service. /// @@ -52,18 +43,7 @@ namespace Umbraco.Core.Composing /// The type of the service. IEnumerable GetAllInstances() where TService : class; - - /// - /// Releases an instance. - /// - /// The instance. - /// - /// See https://stackoverflow.com/questions/14072208 and http://kozmic.net/2010/08/27/must-i-release-everything-when-using-windsor/, - /// you only need to release instances you specifically resolved, and even then, if done right, that might never be needed. For - /// instance, LightInject does not require this and does not support it - should work with scopes. - /// - void Release(object instance); - + /// /// Begins a scope. /// @@ -72,13 +52,5 @@ namespace Umbraco.Core.Composing /// Scopes can be nested. Each instance is disposed individually. /// IDisposable BeginScope(); - - /// - /// Enables per-request scope. - /// - /// - /// Ties scopes to web requests. - /// - void EnablePerWebRequestScope(); } } diff --git a/src/Umbraco.Core/Composing/IRegister.cs b/src/Umbraco.Core/Composing/IRegister.cs index 01f7902c2e..f00d8ac071 100644 --- a/src/Umbraco.Core/Composing/IRegister.cs +++ b/src/Umbraco.Core/Composing/IRegister.cs @@ -7,11 +7,6 @@ namespace Umbraco.Core.Composing /// public interface IRegister { - /// - /// Gets the concrete container. - /// - object Concrete { get; } - /// /// Registers a service as its own implementation. /// @@ -33,69 +28,8 @@ namespace Umbraco.Core.Composing /// void Register(Type serviceType, object instance); - /// - /// Registers a service for a target, as its own implementation. - /// - /// - /// There can only be one implementation or instanced registered for a service and target; - /// what happens if many are registered is not specified. - /// - void RegisterFor(Lifetime lifetime = Lifetime.Transient) - where TService : class; - - /// - /// Registers a service for a target, with an implementation type. - /// - /// - /// There can only be one implementation or instanced registered for a service and target; - /// what happens if many are registered is not specified. - /// - void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient) - where TService : class; - - /// - /// Registers a service for a target, with an implementation factory. - /// - /// - /// There can only be one implementation or instanced registered for a service and target; - /// what happens if many are registered is not specified. - /// - void RegisterFor(Func factory, Lifetime lifetime = Lifetime.Transient) - where TService : class; - - /// - /// Registers a service for a target, with an implementing instance. - /// - /// - /// There can only be one implementation or instanced registered for a service and target; - /// what happens if many are registered is not specified. - /// - void RegisterFor(TService instance) - where TService : class; - - /// - /// Registers a base type for auto-registration. - /// - /// - /// Auto-registration means that anytime the container is asked to create an instance - /// of a type deriving from , it will first register that - /// type automatically. - /// This can be used for instance for views or controllers. Then, one just needs to - /// register a common base class or interface, and the container knows how to create instances. - /// - void RegisterAuto(Type serviceBaseType); - #region Control - /// - /// Configures the container for web support. - /// - /// - /// Enables support for MVC, WebAPI, but *not* per-request scope. This is used early in the boot - /// process, where anything "scoped" should not be linked to a web request. - /// - void ConfigureForWeb(); // TODO: Unsure if we need this anymore - /// /// Creates the factory. /// diff --git a/src/Umbraco.Core/Composing/TargetedServiceFactory.cs b/src/Umbraco.Core/Composing/TargetedServiceFactory.cs deleted file mode 100644 index 53022c0043..0000000000 --- a/src/Umbraco.Core/Composing/TargetedServiceFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Umbraco.Core.Composing -{ - /// - /// Provides a base class for targeted service factories. - /// - /// - public abstract class TargetedServiceFactory - { - private readonly IFactory _factory; - - protected TargetedServiceFactory(IFactory factory) - { - _factory = factory; - } - - public TService For() => _factory.GetInstanceFor(); - } -} diff --git a/src/Umbraco.Core/CompositionExtensions.cs b/src/Umbraco.Core/CompositionExtensions.cs index 5b9abeeb45..218e2a04e3 100644 --- a/src/Umbraco.Core/CompositionExtensions.cs +++ b/src/Umbraco.Core/CompositionExtensions.cs @@ -1,11 +1,11 @@ using Umbraco.Core.Composing; +using Umbraco.Core.HealthCheck; using Umbraco.Core.Manifest; using Umbraco.Core.PropertyEditors; using Umbraco.Web.Actions; using Umbraco.Web.ContentApps; using Umbraco.Web.Dashboards; using Umbraco.Web.Editors; -using Umbraco.Web.HealthCheck; using Umbraco.Web.Routing; using Umbraco.Web.Sections; using Umbraco.Web.Tour; diff --git a/src/Umbraco.Core/CompositionExtensions_Uniques.cs b/src/Umbraco.Core/CompositionExtensions_Uniques.cs index 8352eb33ec..cc08889c2d 100644 --- a/src/Umbraco.Core/CompositionExtensions_Uniques.cs +++ b/src/Umbraco.Core/CompositionExtensions_Uniques.cs @@ -19,13 +19,6 @@ namespace Umbraco.Core public static void RegisterUnique(this Composition composition) => composition.RegisterUnique(typeof(TService), typeof(TImplementing)); - /// - /// Registers a unique service with an implementation type, for a target. - /// - public static void RegisterUniqueFor(this Composition composition) - where TService : class - => composition.RegisterUniqueFor(typeof(TImplementing)); - /// /// Registers a unique service with an implementing instance. /// diff --git a/src/Umbraco.Core/Configuration/HealthChecks/AbstractConfigCheck.cs b/src/Umbraco.Core/Configuration/HealthChecks/AbstractConfigCheck.cs deleted file mode 100644 index f3452131f0..0000000000 --- a/src/Umbraco.Core/Configuration/HealthChecks/AbstractConfigCheck.cs +++ /dev/null @@ -1,234 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.Extensions.Logging; -using Umbraco.Core.Hosting; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using Umbraco.Core.Services; - -namespace Umbraco.Web.HealthCheck.Checks.Config -{ - public abstract class AbstractConfigCheck : HealthCheck - { - private readonly IHostingEnvironment _hostingEnvironment; - private readonly ConfigurationService _configurationService; - - protected ILocalizedTextService TextService { get; } - protected ILoggerFactory LoggerFactory { get; } - - /// - /// Gets the config file path. - /// - public abstract string FilePath { get; } - - /// - /// Gets XPath statement to the config element to check. - /// - public abstract string XPath { get; } - - /// - /// Gets the values to compare against. - /// - public abstract IEnumerable Values { get; } - - /// - /// Gets the current value - /// - public string CurrentValue { get; set; } - - /// - /// Gets the provided value - /// - public string ProvidedValue { get; set; } - - /// - /// Gets the comparison type for checking the value. - /// - public abstract ValueComparisonType ValueComparisonType { get; } - - /// - /// Gets the flag indicating if the check is considered successful if the config value is missing (defaults to false - an error - if missing) - /// - public virtual bool ValidIfConfigMissing - { - get { return false; } - } - - protected AbstractConfigCheck(ILocalizedTextService textService, IHostingEnvironment hostingEnvironment, ILoggerFactory loggerFactory) - { - _hostingEnvironment = hostingEnvironment; - TextService = textService; - LoggerFactory = loggerFactory; - _configurationService = new ConfigurationService(AbsoluteFilePath, XPath, textService, loggerFactory.CreateLogger()); - } - - /// - /// Gets the name of the file. - /// - private string FileName => Path.GetFileName(FilePath); - - /// - /// Gets the absolute file path. - /// - private string AbsoluteFilePath => _hostingEnvironment.MapPathContentRoot(FilePath); - - /// - /// Gets the message for when the check has succeeded. - /// - public virtual string CheckSuccessMessage - { - get - { - return TextService.Localize("healthcheck/checkSuccessMessage", - new[] { CurrentValue, Values.First(v => v.IsRecommended).Value, XPath, AbsoluteFilePath }); - } - } - - /// - /// Gets the message for when the check has failed. - /// - public virtual string CheckErrorMessage - { - get - { - return ValueComparisonType == ValueComparisonType.ShouldEqual - ? TextService.Localize("healthcheck/checkErrorMessageDifferentExpectedValue", - new[] { CurrentValue, Values.First(v => v.IsRecommended).Value, XPath, AbsoluteFilePath }) - : TextService.Localize("healthcheck/checkErrorMessageUnexpectedValue", - new[] { CurrentValue, Values.First(v => v.IsRecommended).Value, XPath, AbsoluteFilePath }); - } - } - - /// - /// Gets the rectify success message. - /// - public virtual string RectifySuccessMessage - { - get - { - var recommendedValue = Values.FirstOrDefault(v => v.IsRecommended); - var rectifiedValue = recommendedValue != null - ? recommendedValue.Value - : ProvidedValue; - return TextService.Localize("healthcheck/rectifySuccessMessage", - new[] - { - CurrentValue, - rectifiedValue, - XPath, - AbsoluteFilePath - }); - } - } - - /// - /// Gets a value indicating whether this check can be rectified automatically. - /// - public virtual bool CanRectify => ValueComparisonType == ValueComparisonType.ShouldEqual; - - /// - /// Gets a value indicating whether this check can be rectified automatically if a value is provided. - /// - public virtual bool CanRectifyWithValue => ValueComparisonType == ValueComparisonType.ShouldNotEqual; - - public override IEnumerable GetStatus() - { - var successMessage = string.Format(CheckSuccessMessage, FileName, XPath, Values); - - var configValue = _configurationService.GetConfigurationValue(); - if (configValue.Success == false) - { - if (ValidIfConfigMissing) - { - return new[] { new HealthCheckStatus(successMessage) { ResultType = StatusResultType.Success } }; - } - - var errorMessage = configValue.Result; - return new[] { new HealthCheckStatus(errorMessage) { ResultType = StatusResultType.Error } }; - } - - CurrentValue = configValue.Result; - - // need to update the successMessage with the CurrentValue - successMessage = string.Format(CheckSuccessMessage, FileName, XPath, Values, CurrentValue); - - var valueFound = Values.Any(value => string.Equals(CurrentValue, value.Value, StringComparison.InvariantCultureIgnoreCase)); - if (ValueComparisonType == ValueComparisonType.ShouldEqual && valueFound || ValueComparisonType == ValueComparisonType.ShouldNotEqual && valueFound == false) - { - return new[] { new HealthCheckStatus(successMessage) { ResultType = StatusResultType.Success } }; - } - - // Declare the action for rectifying the config value - var rectifyAction = new HealthCheckAction("rectify", Id) - { - Name = TextService.Localize("healthcheck/rectifyButton"), - ValueRequired = CanRectifyWithValue, - }; - - var resultMessage = string.Format(CheckErrorMessage, FileName, XPath, Values, CurrentValue); - return new[] - { - new HealthCheckStatus(resultMessage) - { - ResultType = StatusResultType.Error, - Actions = CanRectify || CanRectifyWithValue ? new[] { rectifyAction } : new HealthCheckAction[0] - } - }; - } - - /// - /// Rectifies this check. - /// - /// - public virtual HealthCheckStatus Rectify() - { - if (ValueComparisonType == ValueComparisonType.ShouldNotEqual) - throw new InvalidOperationException(TextService.Localize("healthcheck/cannotRectifyShouldNotEqual")); - - var recommendedValue = Values.First(v => v.IsRecommended).Value; - return UpdateConfigurationValue(recommendedValue); - } - - /// - /// Rectifies this check with a provided value. - /// - /// Value provided - /// - public virtual HealthCheckStatus Rectify(string value) - { - if (ValueComparisonType == ValueComparisonType.ShouldEqual) - throw new InvalidOperationException(TextService.Localize("healthcheck/cannotRectifyShouldEqualWithValue")); - - if (string.IsNullOrWhiteSpace(value)) - throw new InvalidOperationException(TextService.Localize("healthcheck/valueToRectifyNotProvided")); - - // Need to track provided value in order to correctly put together the rectify message - ProvidedValue = value; - - return UpdateConfigurationValue(value); - } - - private HealthCheckStatus UpdateConfigurationValue(string value) - { - var updateConfigFile = _configurationService.UpdateConfigFile(value); - - if (updateConfigFile.Success == false) - { - var message = updateConfigFile.Result; - return new HealthCheckStatus(message) { ResultType = StatusResultType.Error }; - } - - var resultMessage = string.Format(RectifySuccessMessage, FileName, XPath, Values); - return new HealthCheckStatus(resultMessage) { ResultType = StatusResultType.Success }; - } - - public override HealthCheckStatus ExecuteAction(HealthCheckAction action) - { - return string.IsNullOrEmpty(action.ProvidedValue) - ? Rectify() - : Rectify(action.ProvidedValue); - } - } -} diff --git a/src/Umbraco.Core/Configuration/HealthChecks/CompilationDebugCheck.cs b/src/Umbraco.Core/Configuration/HealthChecks/CompilationDebugCheck.cs index b400093a34..a7b99ea205 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/CompilationDebugCheck.cs +++ b/src/Umbraco.Core/Configuration/HealthChecks/CompilationDebugCheck.cs @@ -1,33 +1,41 @@ using System.Collections.Generic; using Microsoft.Extensions.Logging; -using Umbraco.Core.Hosting; -using Umbraco.Core.IO; +using Microsoft.Extensions.Options; +using Umbraco.Core.Configuration.Models; +using Umbraco.Core.HealthCheck; +using Umbraco.Core.HealthCheck.Checks; using Umbraco.Core.Services; -namespace Umbraco.Web.HealthCheck.Checks.Config +namespace Umbraco.Core.Configuration.HealthChecks { [HealthCheck("61214FF3-FC57-4B31-B5CF-1D095C977D6D", "Debug Compilation Mode", Description = "Leaving debug compilation mode enabled can severely slow down a website and take up more memory on the server.", Group = "Live Environment")] - public class CompilationDebugCheck : AbstractConfigCheck + public class CompilationDebugCheck : AbstractSettingsCheck { - public CompilationDebugCheck(ILocalizedTextService textService, IHostingEnvironment hostingEnvironment, ILoggerFactory loggerFactory) - : base(textService, hostingEnvironment, loggerFactory) - { } + private readonly IOptionsMonitor _hostingSettings; - public override string FilePath => "~/Web.config"; + public CompilationDebugCheck(ILocalizedTextService textService, ILoggerFactory loggerFactory, IOptionsMonitor hostingSettings) + : base(textService, loggerFactory) + { + _hostingSettings = hostingSettings; + } - public override string XPath => "/configuration/system.web/compilation/@debug"; + public override string ItemPath => Constants.Configuration.ConfigHostingDebug; public override ValueComparisonType ValueComparisonType => ValueComparisonType.ShouldEqual; - public override bool ValidIfConfigMissing => true; - public override IEnumerable Values => new List { - new AcceptableConfiguration { IsRecommended = true, Value = bool.FalseString.ToLower() } + new AcceptableConfiguration + { + IsRecommended = true, + Value = bool.FalseString.ToLower() + } }; + public override string CurrentValue => _hostingSettings.CurrentValue.Debug.ToString(); + public override string CheckSuccessMessage => TextService.Localize("healthcheck/compilationDebugCheckSuccessMessage"); public override string CheckErrorMessage => TextService.Localize("healthcheck/compilationDebugCheckErrorMessage"); diff --git a/src/Umbraco.Core/Configuration/HealthChecks/ConfigurationService.cs b/src/Umbraco.Core/Configuration/HealthChecks/ConfigurationService.cs index 396d55b735..2459698b7a 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/ConfigurationService.cs +++ b/src/Umbraco.Core/Configuration/HealthChecks/ConfigurationService.cs @@ -1,109 +1,61 @@ using System; -using System.IO; -using System.Xml; using Microsoft.Extensions.Logging; +using Umbraco.Core.HealthCheck; using Umbraco.Core.Services; -namespace Umbraco.Web.HealthCheck.Checks.Config +namespace Umbraco.Core.Configuration.HealthChecks { - // TODO: Add config transform for when config with specified XPath is not found - - public class ConfigurationService + public class ConfigurationService : IConfigurationService { - private readonly string _configFilePath; - private readonly string _xPath; private readonly ILocalizedTextService _textService; private readonly ILogger _logger; + private readonly IConfigManipulator _configManipulator; - /// The absolute file location of the configuration file - /// The XPath to select the value /// /// + /// /// - public ConfigurationService(string configFilePath, string xPath, ILocalizedTextService textService, ILogger logger) + public ConfigurationService(ILocalizedTextService textService, ILogger logger, IConfigManipulator configManipulator) { - _configFilePath = configFilePath; - _xPath = xPath; + if (textService == null) HandleNullParameter(nameof(textService)); + if (configManipulator == null) HandleNullParameter(nameof(configManipulator)); + if (logger == null) HandleNullParameter(nameof(logger)); + + _configManipulator = configManipulator; _textService = textService; _logger = logger; } - /// - /// Gets a value from a given configuration file with the given XPath - /// - public ConfigurationServiceResult GetConfigurationValue() + private void HandleNullParameter(string parameter) { - try - { - if (File.Exists(_configFilePath) == false) - return new ConfigurationServiceResult - { - Success = false, - Result = _textService.Localize("healthcheck/configurationServiceFileNotFound", new[] { _configFilePath }) - }; - - var xmlDocument = new XmlDocument(); - xmlDocument.Load(_configFilePath); - - var xmlNode = xmlDocument.SelectSingleNode(_xPath); - if (xmlNode == null) - return new ConfigurationServiceResult - { - Success = false, - Result = _textService.Localize("healthcheck/configurationServiceNodeNotFound", new[] { _xPath, _configFilePath }) - }; - - return new ConfigurationServiceResult - { - Success = true, - Result = string.Format(xmlNode.Value ?? xmlNode.InnerText) - }; - } - catch (Exception ex) - { - _logger.LogError(ex, "Error trying to get configuration value"); - return new ConfigurationServiceResult - { - Success = false, - Result = _textService.Localize("healthcheck/configurationServiceError", new[] { ex.Message }) - }; - } + _logger.LogError("Error trying to get configuration value", parameter); + throw new ArgumentNullException(parameter); } /// - /// Updates a value in a given configuration file with the given XPath + /// Updates a value in a given configuration file with the given path /// /// + /// /// - public ConfigurationServiceResult UpdateConfigFile(string value) + public ConfigurationServiceResult UpdateConfigFile(string value, string itemPath) { try { - if (File.Exists(_configFilePath) == false) + if (itemPath == null) + { return new ConfigurationServiceResult { Success = false, - Result = _textService.Localize("healthcheck/configurationServiceFileNotFound", new[] { _configFilePath }) + Result = _textService.Localize("healthcheck/configurationServiceNodeNotFound", new[] { itemPath, value }) }; + } - var xmlDocument = new XmlDocument { PreserveWhitespace = true }; - xmlDocument.Load(_configFilePath); - - var node = xmlDocument.SelectSingleNode(_xPath); - if (node == null) - return new ConfigurationServiceResult - { - Success = false, - Result = _textService.Localize("healthcheck/configurationServiceNodeNotFound", new[] { _xPath, _configFilePath }) - }; - - if (node.NodeType == XmlNodeType.Element) - node.InnerText = value; - else - node.Value = value; - - xmlDocument.Save(_configFilePath); - return new ConfigurationServiceResult { Success = true }; + _configManipulator.SaveConfigValue(itemPath, value); + return new ConfigurationServiceResult + { + Success = true + }; } catch (Exception ex) { diff --git a/src/Umbraco.Core/Configuration/HealthChecks/MacroErrorsCheck.cs b/src/Umbraco.Core/Configuration/HealthChecks/MacroErrorsCheck.cs index 68e76dfc81..b31f23667d 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/MacroErrorsCheck.cs +++ b/src/Umbraco.Core/Configuration/HealthChecks/MacroErrorsCheck.cs @@ -1,27 +1,40 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; -using Umbraco.Core.Hosting; -using Umbraco.Core.IO; +using Microsoft.Extensions.Options; +using Umbraco.Core.Configuration.Models; using Umbraco.Core.Services; -namespace Umbraco.Web.HealthCheck.Checks.Config +namespace Umbraco.Core.HealthCheck.Checks.Configuration { [HealthCheck("D0F7599E-9B2A-4D9E-9883-81C7EDC5616F", "Macro errors", - Description = "Checks to make sure macro errors are not set to throw a YSOD (yellow screen of death), which would prevent certain or all pages from loading completely.", + Description = + "Checks to make sure macro errors are not set to throw a YSOD (yellow screen of death), which would prevent certain or all pages from loading completely.", Group = "Configuration")] - public class MacroErrorsCheck : AbstractConfigCheck + public class MacroErrorsCheck : AbstractSettingsCheck { - public MacroErrorsCheck(ILocalizedTextService textService, IHostingEnvironment hostingEnvironment, ILoggerFactory loggerFactory) - : base(textService, hostingEnvironment, loggerFactory) - { } + private readonly ILocalizedTextService _textService; + private readonly ILoggerFactory _loggerFactory; + private readonly IOptionsMonitor _contentSettings; - public override string FilePath => "~/Config/umbracoSettings.config"; - - public override string XPath => "/settings/content/MacroErrors"; + public MacroErrorsCheck(ILocalizedTextService textService, ILoggerFactory loggerFactory, + IOptionsMonitor contentSettings) + : base(textService, loggerFactory) + { + _textService = textService; + _loggerFactory = loggerFactory; + _contentSettings = contentSettings; + } public override ValueComparisonType ValueComparisonType => ValueComparisonType.ShouldEqual; + public override string ItemPath => Constants.Configuration.ConfigContentMacroErrors; + + + /// + /// Gets the values to compare against. + /// public override IEnumerable Values { get @@ -44,24 +57,35 @@ namespace Umbraco.Web.HealthCheck.Checks.Config } } + public override string CurrentValue => _contentSettings.CurrentValue.MacroErrors.ToString(); + + /// + /// Gets the message for when the check has succeeded. + /// public override string CheckSuccessMessage { get { - return TextService.Localize("healthcheck/macroErrorModeCheckSuccessMessage", + return _textService.Localize("healthcheck/macroErrorModeCheckSuccessMessage", new[] { CurrentValue, Values.First(v => v.IsRecommended).Value }); } } + /// + /// Gets the message for when the check has failed. + /// public override string CheckErrorMessage { get { - return TextService.Localize("healthcheck/macroErrorModeCheckErrorMessage", + return _textService.Localize("healthcheck/macroErrorModeCheckErrorMessage", new[] { CurrentValue, Values.First(v => v.IsRecommended).Value }); } } + /// + /// Gets the rectify success message. + /// public override string RectifySuccessMessage { get diff --git a/src/Umbraco.Core/Configuration/HealthChecks/TrySkipIisCustomErrorsCheck.cs b/src/Umbraco.Core/Configuration/HealthChecks/TrySkipIisCustomErrorsCheck.cs index 76269d961c..9710080f35 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/TrySkipIisCustomErrorsCheck.cs +++ b/src/Umbraco.Core/Configuration/HealthChecks/TrySkipIisCustomErrorsCheck.cs @@ -2,32 +2,40 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Umbraco.Core.Configuration.Models; using Umbraco.Core.Hosting; -using Umbraco.Core.IO; using Umbraco.Core.Services; -namespace Umbraco.Web.HealthCheck.Checks.Config +namespace Umbraco.Core.HealthCheck.Checks.Configuration { + [Obsolete("This is not currently in the appsettings.JSON and so can either be removed, or rewritten in .NET Core fashion")] [HealthCheck("046A066C-4FB2-4937-B931-069964E16C66", "Try Skip IIS Custom Errors", Description = "Starting with IIS 7.5, this must be set to true for Umbraco 404 pages to show. Otherwise, IIS will takeover and render its built-in error page.", Group = "Configuration")] - public class TrySkipIisCustomErrorsCheck : AbstractConfigCheck + public class TrySkipIisCustomErrorsCheck : AbstractSettingsCheck { + private readonly ILocalizedTextService _textService; + private readonly ILoggerFactory _loggerFactory; private readonly Version _iisVersion; + private readonly GlobalSettings _globalSettings; - public TrySkipIisCustomErrorsCheck(ILocalizedTextService textService, ILoggerFactory loggerFactory, - IHostingEnvironment hostingEnvironment) - : base(textService, hostingEnvironment, loggerFactory) + public TrySkipIisCustomErrorsCheck(ILocalizedTextService textService, ILoggerFactory loggerFactory, IOptions globalSettings) + : base(textService, loggerFactory) { - _iisVersion = hostingEnvironment.IISVersion; + _textService = textService; + _loggerFactory = loggerFactory; + //TODO: detect if hosted in IIS, and then IIS version if we want to go this route + _iisVersion = new Version("7.5"); + _globalSettings = globalSettings.Value; } - public override string FilePath => "~/Config/umbracoSettings.config"; - - public override string XPath => "/settings/web.routing/@trySkipIisCustomErrors"; + public override string ItemPath => "TBC"; public override ValueComparisonType ValueComparisonType => ValueComparisonType.ShouldEqual; + public override string CurrentValue => null; + public override IEnumerable Values { get @@ -36,7 +44,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Config var recommendedValue = _iisVersion >= new Version("7.5") ? bool.TrueString.ToLower() : bool.FalseString.ToLower(); - return new List { new AcceptableConfiguration { IsRecommended = true, Value = recommendedValue } }; + return new List { new AcceptableConfiguration { IsRecommended = true, Value = recommendedValue } }; } } @@ -44,7 +52,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Config { get { - return TextService.Localize("healthcheck/trySkipIisCustomErrorsCheckSuccessMessage", + return _textService.Localize("healthcheck/trySkipIisCustomErrorsCheckSuccessMessage", new[] { Values.First(v => v.IsRecommended).Value, _iisVersion.ToString() }); } } @@ -53,7 +61,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Config { get { - return TextService.Localize("healthcheck/trySkipIisCustomErrorsCheckErrorMessage", + return _textService.Localize("healthcheck/trySkipIisCustomErrorsCheckErrorMessage", new[] { CurrentValue, Values.First(v => v.IsRecommended).Value, _iisVersion.ToString() }); } } @@ -62,8 +70,10 @@ namespace Umbraco.Web.HealthCheck.Checks.Config { get { - return TextService.Localize("healthcheck/trySkipIisCustomErrorsCheckRectifySuccessMessage", - new[] { Values.First(v => v.IsRecommended).Value, _iisVersion.ToString() }); + return _textService.Localize("healthcheck/trySkipIisCustomErrorsCheckRectifySuccessMessage", + new[] { "Not implemented" }); + + //new[] { Values.First(v => v.IsRecommended).Value, _iisVersion.ToString() }); } } } diff --git a/src/Umbraco.Core/Configuration/Models/HealthChecksSettings.cs b/src/Umbraco.Core/Configuration/Models/HealthChecksSettings.cs index 0903a8f242..7600b946fd 100644 --- a/src/Umbraco.Core/Configuration/Models/HealthChecksSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/HealthChecksSettings.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; -using Umbraco.Core.Configuration.HealthChecks; +using Umbraco.Core.HealthCheck; +using Umbraco.Core.HealthCheck.Checks; namespace Umbraco.Core.Configuration.Models { diff --git a/src/Umbraco.Core/Configuration/Models/ImagingCacheSettings.cs b/src/Umbraco.Core/Configuration/Models/ImagingCacheSettings.cs index 90249abc15..44f5ae89b6 100644 --- a/src/Umbraco.Core/Configuration/Models/ImagingCacheSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/ImagingCacheSettings.cs @@ -12,6 +12,6 @@ namespace Umbraco.Core.Configuration.Models public uint CachedNameLength { get; set; } = 8; - public string CacheFolder { get; set; } = Path.Combine("..", "Umbraco", "MediaCache"); + public string CacheFolder { get; set; } = Path.Combine("..", "umbraco", "mediacache"); } } diff --git a/src/Umbraco.Core/Configuration/Models/ModelsBuilderSettings.cs b/src/Umbraco.Core/Configuration/Models/ModelsBuilderSettings.cs index 9667a5eb2d..f0b56561e2 100644 --- a/src/Umbraco.Core/Configuration/Models/ModelsBuilderSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/ModelsBuilderSettings.cs @@ -5,10 +5,10 @@ namespace Umbraco.Core.Configuration.Models /// /// Represents the models builder configuration. /// - public class ModelsBuilderSettings + public class ModelsBuilderSettings { // TODO: This should not go into App_Data - that folder isn't really a real thing anymore - public static string DefaultModelsDirectory => "~/App_Data/Models"; + public static string DefaultModelsDirectory => "~/umbraco/models"; /// /// Gets a value indicating whether the whole models experience is enabled. diff --git a/src/Umbraco.Core/Constants-Configuration.cs b/src/Umbraco.Core/Constants-Configuration.cs index c06ec8f1ec..2c9fe3caee 100644 --- a/src/Umbraco.Core/Constants-Configuration.cs +++ b/src/Umbraco.Core/Constants-Configuration.cs @@ -11,9 +11,23 @@ /// ":" is used as marker for nested objects in json. E.g. "Umbraco:CMS:" = {"Umbraco":{"CMS":{....}} /// public const string ConfigPrefix = "Umbraco:CMS:"; + public const string ConfigContentPrefix = ConfigPrefix + "Content:"; + public const string ConfigContentNotificationsPrefix = ConfigContentPrefix + "Notifications:"; + public const string ConfigCorePrefix = ConfigPrefix + "Core:"; + public const string ConfigCustomErrorsPrefix = ConfigPrefix + "CustomErrors:"; + public const string ConfigGlobalPrefix = ConfigPrefix + "Global:"; + public const string ConfigHostingPrefix = ConfigPrefix + "Hosting:"; + public const string ConfigModelsBuilderPrefix = ConfigPrefix + "ModelsBuilder:"; + public const string ConfigSecurityPrefix = ConfigPrefix + "Security:"; + + public const string ConfigContentNotificationsEmail = ConfigContentNotificationsPrefix + "Email"; + public const string ConfigContentMacroErrors = ConfigContentPrefix + "MacroErrors"; + public const string ConfigGlobalUseHttps = ConfigGlobalPrefix + "UseHttps"; + public const string ConfigHostingDebug = ConfigHostingPrefix + "Debug"; + public const string ConfigCustomErrorsMode = ConfigCustomErrorsPrefix + "Mode"; public const string ConfigActiveDirectory = ConfigPrefix + "ActiveDirectory"; public const string ConfigContent = ConfigPrefix + "Content"; - public const string ConfigCoreDebug = ConfigPrefix + "Core:Debug"; + public const string ConfigCoreDebug = ConfigCorePrefix + "Debug"; public const string ConfigExceptionFilter = ConfigPrefix + "ExceptionFilter"; public const string ConfigGlobal = ConfigPrefix + "Global"; public const string ConfigHealthChecks = ConfigPrefix + "HealthChecks"; @@ -27,14 +41,13 @@ public const string ConfigNuCache = ConfigPrefix + "NuCache"; public const string ConfigRequestHandler = ConfigPrefix + "RequestHandler"; public const string ConfigRuntime = ConfigPrefix + "Runtime"; + public const string ConfigRuntimeMinification = ConfigPrefix + "RuntimeMinification"; + public const string ConfigRuntimeMinificationVersion = ConfigRuntimeMinification + ":Version"; public const string ConfigSecurity = ConfigPrefix + "Security"; public const string ConfigTours = ConfigPrefix + "Tours"; public const string ConfigTypeFinder = ConfigPrefix + "TypeFinder"; public const string ConfigWebRouting = ConfigPrefix + "WebRouting"; public const string ConfigUserPassword = ConfigPrefix + "Security:UserPassword"; - - public const string ConfigRuntimeMinification = ConfigPrefix + "RuntimeMinification"; - public const string ConfigRuntimeMinificationVersion = ConfigRuntimeMinification + ":Version"; } } } diff --git a/src/Umbraco.Core/Events/SendEmailEventArgs.cs b/src/Umbraco.Core/Events/SendEmailEventArgs.cs index cfe43233cd..7ee9469b57 100644 --- a/src/Umbraco.Core/Events/SendEmailEventArgs.cs +++ b/src/Umbraco.Core/Events/SendEmailEventArgs.cs @@ -1,13 +1,13 @@ using System; -using System.Net.Mail; +using Umbraco.Core.Models; namespace Umbraco.Core.Events { public class SendEmailEventArgs : EventArgs { - public MailMessage Message { get; private set; } + public EmailMessage Message { get; } - public SendEmailEventArgs(MailMessage message) + public SendEmailEventArgs(EmailMessage message) { Message = message; } diff --git a/src/Umbraco.Core/Configuration/HealthChecks/AcceptableConfiguration.cs b/src/Umbraco.Core/HealthCheck/AcceptableConfiguration.cs similarity index 74% rename from src/Umbraco.Core/Configuration/HealthChecks/AcceptableConfiguration.cs rename to src/Umbraco.Core/HealthCheck/AcceptableConfiguration.cs index b71bba1d14..f879172a5d 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/AcceptableConfiguration.cs +++ b/src/Umbraco.Core/HealthCheck/AcceptableConfiguration.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Web.HealthCheck.Checks.Config +namespace Umbraco.Core.HealthCheck { public class AcceptableConfiguration { diff --git a/src/Umbraco.Core/HealthCheck/Checks/AbstractSettingsCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/AbstractSettingsCheck.cs new file mode 100644 index 0000000000..62543dcfbd --- /dev/null +++ b/src/Umbraco.Core/HealthCheck/Checks/AbstractSettingsCheck.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.Logging; +using Umbraco.Core.Services; + +namespace Umbraco.Core.HealthCheck.Checks +{ + public abstract class AbstractSettingsCheck : HealthCheck + { + protected ILocalizedTextService TextService { get; } + protected ILoggerFactory LoggerFactory { get; } + + /// + /// Gets key within the JSON to check, in the colon-delimited format + /// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1 + /// + public abstract string ItemPath { get; } + + /// + /// Gets the values to compare against. + /// + public abstract IEnumerable Values { get; } + + /// + /// Gets the current value of the config setting + /// + public abstract string CurrentValue { get; } + + /// + /// Gets the provided value + /// + public string ProvidedValue { get; set; } + + /// + /// Gets the comparison type for checking the value. + /// + public abstract ValueComparisonType ValueComparisonType { get; } + + protected AbstractSettingsCheck(ILocalizedTextService textService, ILoggerFactory loggerFactory) + { + TextService = textService; + LoggerFactory = loggerFactory; + } + + /// + /// Gets the message for when the check has succeeded. + /// + public virtual string CheckSuccessMessage + { + get + { + return TextService.Localize("healthcheck/checkSuccessMessage", new[] { CurrentValue, Values.First(v => v.IsRecommended).Value, ItemPath }); + } + } + + /// + /// Gets the message for when the check has failed. + /// + public virtual string CheckErrorMessage + { + get + { + return ValueComparisonType == ValueComparisonType.ShouldEqual + ? TextService.Localize("healthcheck/checkErrorMessageDifferentExpectedValue", + new[] { CurrentValue, Values.First(v => v.IsRecommended).Value, ItemPath }) + : TextService.Localize("healthcheck/checkErrorMessageUnexpectedValue", + new[] { CurrentValue, Values.First(v => v.IsRecommended).Value, ItemPath }); + } + } + + /// + /// Gets the rectify success message. + /// + public virtual string RectifySuccessMessage + { + get + { + AcceptableConfiguration recommendedValue = Values.FirstOrDefault(v => v.IsRecommended); + string rectifiedValue = recommendedValue != null ? recommendedValue.Value : ProvidedValue; + return TextService.Localize("healthcheck/rectifySuccessMessage", + new[] + { + CurrentValue, + rectifiedValue, + ItemPath + }); + } + } + + /// + /// Gets a value indicating whether this check can be rectified automatically. + /// + public virtual bool CanRectify => ValueComparisonType == ValueComparisonType.ShouldEqual; + + /// + /// Gets a value indicating whether this check can be rectified automatically if a value is provided. + /// + public virtual bool CanRectifyWithValue => ValueComparisonType == ValueComparisonType.ShouldNotEqual; + + public override IEnumerable GetStatus() + { + // update the successMessage with the CurrentValue + var successMessage = string.Format(CheckSuccessMessage, ItemPath, Values, CurrentValue); + bool valueFound = Values.Any(value => string.Equals(CurrentValue, value.Value, StringComparison.InvariantCultureIgnoreCase)); + + if (ValueComparisonType == ValueComparisonType.ShouldEqual + && valueFound || ValueComparisonType == ValueComparisonType.ShouldNotEqual + && valueFound == false) + { + return new[] + { + new HealthCheckStatus(successMessage) + { + ResultType = StatusResultType.Success + } + }; + } + + // Declare the action for rectifying the config value + var rectifyAction = new HealthCheckAction("rectify", Id) + { + Name = TextService.Localize("healthcheck/rectifyButton"), + ValueRequired = CanRectifyWithValue + }; + + string resultMessage = string.Format(CheckErrorMessage, ItemPath, Values, CurrentValue); + return new[] + { + new HealthCheckStatus(resultMessage) + { + ResultType = StatusResultType.Error, + Actions = CanRectify || CanRectifyWithValue ? new[] { rectifyAction } : new HealthCheckAction[0] + } + }; + } + + /// + /// Rectifies this check. + /// + /// + public virtual HealthCheckStatus Rectify(HealthCheckAction action) + { + if (ValueComparisonType == ValueComparisonType.ShouldNotEqual) + { + throw new InvalidOperationException(TextService.Localize("healthcheck/cannotRectifyShouldNotEqual")); + } + + //TODO: show message instead of actually fixing config + string recommendedValue = Values.First(v => v.IsRecommended).Value; + string resultMessage = string.Format(RectifySuccessMessage, ItemPath, Values); + return new HealthCheckStatus(resultMessage) { ResultType = StatusResultType.Success }; + } + + public override HealthCheckStatus ExecuteAction(HealthCheckAction action) + { + return Rectify(action); + } + } +} diff --git a/src/Umbraco.Core/Configuration/HealthChecks/NotificationEmailCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Configuration/NotificationEmailCheck.cs similarity index 61% rename from src/Umbraco.Core/Configuration/HealthChecks/NotificationEmailCheck.cs rename to src/Umbraco.Core/HealthCheck/Checks/Configuration/NotificationEmailCheck.cs index bac2cf1c3c..a6e6a83c47 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/NotificationEmailCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Configuration/NotificationEmailCheck.cs @@ -1,25 +1,26 @@ using System.Collections.Generic; using Microsoft.Extensions.Logging; -using Umbraco.Core.Hosting; -using Umbraco.Core.IO; +using Microsoft.Extensions.Options; +using Umbraco.Core.Configuration.Models; using Umbraco.Core.Services; -namespace Umbraco.Web.HealthCheck.Checks.Config +namespace Umbraco.Core.HealthCheck.Checks.Configuration { [HealthCheck("3E2F7B14-4B41-452B-9A30-E67FBC8E1206", "Notification Email Settings", Description = "If notifications are used, the 'from' email address should be specified and changed from the default value.", Group = "Configuration")] - public class NotificationEmailCheck : AbstractConfigCheck + public class NotificationEmailCheck : AbstractSettingsCheck { + private readonly IOptionsMonitor _contentSettings; private const string DefaultFromEmail = "your@email.here"; - public NotificationEmailCheck(ILocalizedTextService textService, IHostingEnvironment hostingEnvironment, ILoggerFactory loggerFactory) - : base(textService, hostingEnvironment, loggerFactory) - { } + public NotificationEmailCheck(ILocalizedTextService textService, ILoggerFactory loggerFactory, IOptionsMonitor contentSettings) + : base(textService, loggerFactory) + { + _contentSettings = contentSettings; + } - public override string FilePath => "~/Config/umbracoSettings.config"; - - public override string XPath => "/settings/content/notifications/email"; + public override string ItemPath => Constants.Configuration.ConfigContentNotificationsEmail; public override ValueComparisonType ValueComparisonType => ValueComparisonType.ShouldNotEqual; @@ -28,8 +29,11 @@ namespace Umbraco.Web.HealthCheck.Checks.Config new AcceptableConfiguration { IsRecommended = false, Value = DefaultFromEmail } }; - public override string CheckSuccessMessage => TextService.Localize("healthcheck/notificationEmailsCheckSuccessMessage", new [] { CurrentValue } ); + public override string CurrentValue => _contentSettings.CurrentValue.Notifications.Email; + + public override string CheckSuccessMessage => TextService.Localize("healthcheck/notificationEmailsCheckSuccessMessage", new[] { CurrentValue }); public override string CheckErrorMessage => TextService.Localize("healthcheck/notificationEmailsCheckErrorMessage", new[] { DefaultFromEmail }); + } } diff --git a/src/Umbraco.Core/HealthCheck/Checks/Data/DatabaseIntegrityCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Data/DatabaseIntegrityCheck.cs index a18edb175a..0fb34950bd 100644 --- a/src/Umbraco.Core/HealthCheck/Checks/Data/DatabaseIntegrityCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Data/DatabaseIntegrityCheck.cs @@ -5,7 +5,7 @@ using System.Text; using Umbraco.Core.Models; using Umbraco.Core.Services; -namespace Umbraco.Web.HealthCheck.Checks.Data +namespace Umbraco.Core.HealthCheck.Checks.Data { [HealthCheck( "73DD0C1C-E0CA-4C31-9564-1DCA509788AF", diff --git a/src/Umbraco.Core/Configuration/HealthChecks/DisabledHealthCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/DisabledHealthCheck.cs similarity index 80% rename from src/Umbraco.Core/Configuration/HealthChecks/DisabledHealthCheck.cs rename to src/Umbraco.Core/HealthCheck/Checks/DisabledHealthCheck.cs index c962014bd5..99ff05ed55 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/DisabledHealthCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/DisabledHealthCheck.cs @@ -1,6 +1,6 @@ using System; -namespace Umbraco.Core.Configuration.HealthChecks +namespace Umbraco.Core.HealthCheck.Checks { public class DisabledHealthCheck { diff --git a/src/Umbraco.Core/Configuration/HealthChecks/CustomErrorsCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/LiveEnvironment/CustomErrorsCheck.cs similarity index 78% rename from src/Umbraco.Core/Configuration/HealthChecks/CustomErrorsCheck.cs rename to src/Umbraco.Core/HealthCheck/Checks/LiveEnvironment/CustomErrorsCheck.cs index 9b14847bdf..b003506205 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/CustomErrorsCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/LiveEnvironment/CustomErrorsCheck.cs @@ -1,24 +1,20 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; -using Umbraco.Core.Hosting; -using Umbraco.Core.IO; using Umbraco.Core.Services; -namespace Umbraco.Web.HealthCheck.Checks.Config +namespace Umbraco.Core.HealthCheck.Checks.LiveEnvironment { [HealthCheck("4090C0A1-2C52-4124-92DD-F028FD066A64", "Custom Errors", Description = "Leaving custom errors off will display a complete stack trace to your visitors if an exception occurs.", Group = "Live Environment")] - public class CustomErrorsCheck : AbstractConfigCheck + public class CustomErrorsCheck : AbstractSettingsCheck { - public CustomErrorsCheck(ILocalizedTextService textService, IHostingEnvironment hostingEnvironment, ILoggerFactory loggerFactory) - : base(textService, hostingEnvironment, loggerFactory) + public CustomErrorsCheck(ILocalizedTextService textService, ILoggerFactory loggerFactory) + : base(textService, loggerFactory) { } - public override string FilePath => "~/Web.config"; - - public override string XPath => "/configuration/system.web/customErrors/@mode"; + public override string ItemPath => Constants.Configuration.ConfigCustomErrorsMode; public override ValueComparisonType ValueComparisonType => ValueComparisonType.ShouldEqual; @@ -28,6 +24,8 @@ namespace Umbraco.Web.HealthCheck.Checks.Config new AcceptableConfiguration { IsRecommended = false, Value = "On" } }; + public override string CurrentValue { get; } + public override string CheckSuccessMessage { get diff --git a/src/Umbraco.Core/Configuration/HealthChecks/TraceCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/LiveEnvironment/TraceCheck.cs similarity index 68% rename from src/Umbraco.Core/Configuration/HealthChecks/TraceCheck.cs rename to src/Umbraco.Core/HealthCheck/Checks/LiveEnvironment/TraceCheck.cs index a2c5a84c55..03a6ecfde2 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/TraceCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/LiveEnvironment/TraceCheck.cs @@ -1,24 +1,19 @@ using System.Collections.Generic; using Microsoft.Extensions.Logging; -using Umbraco.Core.Hosting; -using Umbraco.Core.IO; using Umbraco.Core.Services; -namespace Umbraco.Web.HealthCheck.Checks.Config +namespace Umbraco.Core.HealthCheck.Checks.LiveEnvironment { [HealthCheck("9BED6EF4-A7F3-457A-8935-B64E9AA8BAB3", "Trace Mode", Description = "Leaving trace mode enabled can make valuable information about your system available to hackers.", Group = "Live Environment")] - public class TraceCheck : AbstractConfigCheck + public class TraceCheck : AbstractSettingsCheck { - - public TraceCheck(ILocalizedTextService textService, IHostingEnvironment hostingEnvironment, ILoggerFactory loggerFactory) - : base(textService, hostingEnvironment, loggerFactory) + public TraceCheck(ILocalizedTextService textService, ILoggerFactory loggerFactory) + : base(textService, loggerFactory) { } - public override string FilePath => "~/Web.config"; - - public override string XPath => "/configuration/system.web/trace/@enabled"; + public override string ItemPath => "/configuration/system.web/trace/@enabled"; public override ValueComparisonType ValueComparisonType => ValueComparisonType.ShouldEqual; @@ -27,10 +22,13 @@ namespace Umbraco.Web.HealthCheck.Checks.Config new AcceptableConfiguration { IsRecommended = true, Value = bool.FalseString.ToLower() } }; + public override string CurrentValue { get; } + public override string CheckSuccessMessage => TextService.Localize("healthcheck/traceModeCheckSuccessMessage"); public override string CheckErrorMessage => TextService.Localize("healthcheck/traceModeCheckErrorMessage"); public override string RectifySuccessMessage => TextService.Localize("healthcheck/traceModeCheckRectifySuccessMessage"); + } } diff --git a/src/Umbraco.Core/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs index d6fbfae813..1618daf028 100644 --- a/src/Umbraco.Core/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs @@ -2,27 +2,13 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Options; -using Umbraco.Core; -using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Install; using Umbraco.Core.IO; using Umbraco.Core.Services; -namespace Umbraco.Web.HealthCheck.Checks.Permissions +namespace Umbraco.Core.HealthCheck.Checks.Permissions { - internal enum PermissionCheckRequirement - { - Required, - Optional - } - - internal enum PermissionCheckFor - { - Folder, - File - } - [HealthCheck( "53DBA282-4A79-4B67-B958-B29EC40FCC23", "Folder & File Permissions", @@ -31,14 +17,14 @@ namespace Umbraco.Web.HealthCheck.Checks.Permissions public class FolderAndFilePermissionsCheck : HealthCheck { private readonly ILocalizedTextService _textService; - private readonly GlobalSettings _globalSettings; + private readonly IOptionsMonitor _globalSettings; private readonly IFilePermissionHelper _filePermissionHelper; private readonly IIOHelper _ioHelper; - public FolderAndFilePermissionsCheck(ILocalizedTextService textService, IOptions globalSettings, IFilePermissionHelper filePermissionHelper, IIOHelper ioHelper) + public FolderAndFilePermissionsCheck(ILocalizedTextService textService, IOptionsMonitor globalSettings, IFilePermissionHelper filePermissionHelper, IIOHelper ioHelper) { _textService = textService; - _globalSettings = globalSettings.Value; + _globalSettings = globalSettings; _filePermissionHelper = filePermissionHelper; _ioHelper = ioHelper; } @@ -74,10 +60,10 @@ namespace Umbraco.Web.HealthCheck.Checks.Permissions { Constants.SystemDirectories.Preview, PermissionCheckRequirement.Required }, { Constants.SystemDirectories.AppPlugins, PermissionCheckRequirement.Required }, { Constants.SystemDirectories.Config, PermissionCheckRequirement.Optional }, - { _globalSettings.UmbracoCssPath, PermissionCheckRequirement.Optional }, - { _globalSettings.UmbracoMediaPath, PermissionCheckRequirement.Optional }, - { _globalSettings.UmbracoScriptsPath, PermissionCheckRequirement.Optional }, - { _globalSettings.UmbracoPath, PermissionCheckRequirement.Optional }, + { _globalSettings.CurrentValue.UmbracoCssPath, PermissionCheckRequirement.Optional }, + { _globalSettings.CurrentValue.UmbracoMediaPath, PermissionCheckRequirement.Optional }, + { _globalSettings.CurrentValue.UmbracoScriptsPath, PermissionCheckRequirement.Optional }, + { _globalSettings.CurrentValue.UmbracoPath, PermissionCheckRequirement.Optional }, { Constants.SystemDirectories.MvcViews, PermissionCheckRequirement.Optional } }; @@ -97,7 +83,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Permissions //now check the special folders var requiredPathCheckResult2 = _filePermissionHelper.EnsureDirectories( - GetPathsToCheck(pathsToCheckWithRestarts, PermissionCheckRequirement.Required), out var requiredFailedPaths2, writeCausesRestart:true); + GetPathsToCheck(pathsToCheckWithRestarts, PermissionCheckRequirement.Required), out var requiredFailedPaths2, writeCausesRestart: true); var optionalPathCheckResult2 = _filePermissionHelper.EnsureDirectories( GetPathsToCheck(pathsToCheckWithRestarts, PermissionCheckRequirement.Optional), out var optionalFailedPaths2, writeCausesRestart: true); @@ -139,9 +125,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Permissions .ToArray(); } - private HealthCheckStatus GetStatus(bool requiredPathCheckResult, IEnumerable requiredFailedPaths, - bool optionalPathCheckResult, IEnumerable optionalFailedPaths, - PermissionCheckFor checkingFor) + private HealthCheckStatus GetStatus(bool requiredPathCheckResult, IEnumerable requiredFailedPaths, bool optionalPathCheckResult, IEnumerable optionalFailedPaths, PermissionCheckFor checkingFor) { // Return error if any required paths fail the check, or warning if any optional ones do var resultType = StatusResultType.Success; @@ -164,12 +148,11 @@ namespace Umbraco.Web.HealthCheck.Checks.Permissions } var actions = new List(); - return - new HealthCheckStatus(message) - { - ResultType = resultType, - Actions = actions - }; + return new HealthCheckStatus(message) + { + ResultType = resultType, + Actions = actions + }; } private string GetMessageForPathCheckFailure(string messageKey, IEnumerable failedPaths) diff --git a/src/Umbraco.Core/HealthCheck/Checks/Permissions/PermissionCheckFor.cs b/src/Umbraco.Core/HealthCheck/Checks/Permissions/PermissionCheckFor.cs new file mode 100644 index 0000000000..bd914d064d --- /dev/null +++ b/src/Umbraco.Core/HealthCheck/Checks/Permissions/PermissionCheckFor.cs @@ -0,0 +1,8 @@ +namespace Umbraco.Core.HealthCheck.Checks.Permissions +{ + internal enum PermissionCheckFor + { + Folder, + File + } +} diff --git a/src/Umbraco.Core/HealthCheck/Checks/Permissions/PermissionCheckRequirement.cs b/src/Umbraco.Core/HealthCheck/Checks/Permissions/PermissionCheckRequirement.cs new file mode 100644 index 0000000000..f77fdbf2e3 --- /dev/null +++ b/src/Umbraco.Core/HealthCheck/Checks/Permissions/PermissionCheckRequirement.cs @@ -0,0 +1,8 @@ +namespace Umbraco.Core.HealthCheck.Checks.Permissions +{ + internal enum PermissionCheckRequirement + { + Required, + Optional + } +} diff --git a/src/Umbraco.Core/HealthCheck/Checks/Security/BaseHttpHeaderCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Security/BaseHttpHeaderCheck.cs index 149ad4a48a..5bf92342bf 100644 --- a/src/Umbraco.Core/HealthCheck/Checks/Security/BaseHttpHeaderCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Security/BaseHttpHeaderCheck.cs @@ -4,13 +4,11 @@ using System.IO; using System.Linq; using System.Net; using System.Text.RegularExpressions; -using System.Xml.Linq; -using System.Xml.XPath; -using Umbraco.Core; -using Umbraco.Core.IO; +using Microsoft.Extensions.Configuration; using Umbraco.Core.Services; +using Umbraco.Web; -namespace Umbraco.Web.HealthCheck.Checks.Security +namespace Umbraco.Core.HealthCheck.Checks.Security { public abstract class BaseHttpHeaderCheck : HealthCheck { @@ -23,16 +21,14 @@ namespace Umbraco.Web.HealthCheck.Checks.Security private readonly string _localizedTextPrefix; private readonly bool _metaTagOptionAvailable; private readonly IRequestAccessor _requestAccessor; - private readonly IIOHelper _ioHelper; protected BaseHttpHeaderCheck( IRequestAccessor requestAccessor, ILocalizedTextService textService, - string header, string value, string localizedTextPrefix, bool metaTagOptionAvailable, IIOHelper ioHelper) + string header, string value, string localizedTextPrefix, bool metaTagOptionAvailable) { TextService = textService ?? throw new ArgumentNullException(nameof(textService)); _requestAccessor = requestAccessor; - _ioHelper = ioHelper; _header = header; _value = value; _localizedTextPrefix = localizedTextPrefix; @@ -72,7 +68,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Security var success = false; // Access the site home page and check for the click-jack protection header or meta tag - var url = _requestAccessor.GetApplicationUrl(); + var url = _requestAccessor.GetApplicationUrl(); var request = WebRequest.Create(url); request.Method = "GET"; try @@ -146,7 +142,8 @@ namespace Umbraco.Web.HealthCheck.Checks.Security private HealthCheckStatus SetHeaderInConfig() { var errorMessage = string.Empty; - var success = SaveHeaderToConfigFile(out errorMessage); + //TODO: edit to show fix suggestion instead of making fix + var success = true; if (success) { @@ -158,64 +155,10 @@ namespace Umbraco.Web.HealthCheck.Checks.Security } return - new HealthCheckStatus(TextService.Localize("healthcheck/setHeaderInConfigError", new [] { errorMessage })) + new HealthCheckStatus(TextService.Localize("healthcheck/setHeaderInConfigError", new[] { errorMessage })) { ResultType = StatusResultType.Error }; } - - private bool SaveHeaderToConfigFile(out string errorMessage) - { - try - { - // There don't look to be any useful classes defined in https://msdn.microsoft.com/en-us/library/system.web.configuration(v=vs.110).aspx - // for working with the customHeaders section, so working with the XML directly. - var configFile = _ioHelper.MapPath("~/Web.config"); - var doc = XDocument.Load(configFile); - var systemWebServerElement = doc.XPathSelectElement("/configuration/system.webServer"); - var httpProtocolElement = systemWebServerElement.Element("httpProtocol"); - if (httpProtocolElement == null) - { - httpProtocolElement = new XElement("httpProtocol"); - systemWebServerElement.Add(httpProtocolElement); - } - - var customHeadersElement = httpProtocolElement.Element("customHeaders"); - if (customHeadersElement == null) - { - customHeadersElement = new XElement("customHeaders"); - httpProtocolElement.Add(customHeadersElement); - } - - var removeHeaderElement = customHeadersElement.Elements("remove") - .SingleOrDefault(x => x.Attribute("name")?.Value.Equals(_value, StringComparison.InvariantCultureIgnoreCase) == true); - if (removeHeaderElement == null) - { - customHeadersElement.Add( - new XElement("remove", - new XAttribute("name", _header))); - } - - var addHeaderElement = customHeadersElement.Elements("add") - .SingleOrDefault(x => x.Attribute("name")?.Value.Equals(_header, StringComparison.InvariantCultureIgnoreCase) == true); - if (addHeaderElement == null) - { - customHeadersElement.Add( - new XElement("add", - new XAttribute("name", _header), - new XAttribute("value", _value))); - } - - doc.Save(configFile); - - errorMessage = string.Empty; - return true; - } - catch (Exception ex) - { - errorMessage = ex.Message; - return false; - } - } } } diff --git a/src/Umbraco.Core/HealthCheck/Checks/Security/ClickJackingCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Security/ClickJackingCheck.cs index 048b26afca..a7b4c0ba85 100644 --- a/src/Umbraco.Core/HealthCheck/Checks/Security/ClickJackingCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Security/ClickJackingCheck.cs @@ -1,8 +1,7 @@ -using Umbraco.Core; -using Umbraco.Core.IO; -using Umbraco.Core.Services; +using Umbraco.Core.Services; +using Umbraco.Web; -namespace Umbraco.Web.HealthCheck.Checks.Security +namespace Umbraco.Core.HealthCheck.Checks.Security { [HealthCheck( "ED0D7E40-971E-4BE8-AB6D-8CC5D0A6A5B0", @@ -11,8 +10,8 @@ namespace Umbraco.Web.HealthCheck.Checks.Security Group = "Security")] public class ClickJackingCheck : BaseHttpHeaderCheck { - public ClickJackingCheck(IRequestAccessor requestAccessor, ILocalizedTextService textService, IIOHelper ioHelper) - : base(requestAccessor, textService, "X-Frame-Options", "sameorigin", "clickJacking", true, ioHelper) + public ClickJackingCheck(IRequestAccessor requestAccessor, ILocalizedTextService textService) + : base(requestAccessor, textService, "X-Frame-Options", "sameorigin", "clickJacking", true) { } } diff --git a/src/Umbraco.Core/HealthCheck/Checks/Security/ExcessiveHeadersCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Security/ExcessiveHeadersCheck.cs index 06367ace13..9cf1127bb0 100644 --- a/src/Umbraco.Core/HealthCheck/Checks/Security/ExcessiveHeadersCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Security/ExcessiveHeadersCheck.cs @@ -2,10 +2,10 @@ using System.Collections.Generic; using System.Linq; using System.Net; -using Umbraco.Core; using Umbraco.Core.Services; +using Umbraco.Web; -namespace Umbraco.Web.HealthCheck.Checks.Security +namespace Umbraco.Core.HealthCheck.Checks.Security { [HealthCheck( "92ABBAA2-0586-4089-8AE2-9A843439D577", diff --git a/src/Umbraco.Core/HealthCheck/Checks/Security/HstsCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Security/HstsCheck.cs index 61879142f2..ee8f733fca 100644 --- a/src/Umbraco.Core/HealthCheck/Checks/Security/HstsCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Security/HstsCheck.cs @@ -1,8 +1,7 @@ -using Umbraco.Core; -using Umbraco.Core.IO; -using Umbraco.Core.Services; +using Umbraco.Core.Services; +using Umbraco.Web; -namespace Umbraco.Web.HealthCheck.Checks.Security +namespace Umbraco.Core.HealthCheck.Checks.Security { [HealthCheck( "E2048C48-21C5-4BE1-A80B-8062162DF124", @@ -16,8 +15,8 @@ namespace Umbraco.Web.HealthCheck.Checks.Security // and the blog post of Troy Hunt (https://www.troyhunt.com/understanding-http-strict-transport/) // If you want do to it perfectly, you have to submit it https://hstspreload.org/, // but then you should include subdomains and I wouldn't suggest to do that for Umbraco-sites. - public HstsCheck(IRequestAccessor requestAccessor, ILocalizedTextService textService, IIOHelper ioHelper) - : base(requestAccessor, textService, "Strict-Transport-Security", "max-age=10886400", "hSTS", true, ioHelper) + public HstsCheck(IRequestAccessor requestAccessor, ILocalizedTextService textService) + : base(requestAccessor, textService, "Strict-Transport-Security", "max-age=10886400", "hSTS", true) { } } diff --git a/src/Umbraco.Core/HealthCheck/Checks/Security/HttpsCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Security/HttpsCheck.cs index 3f788f7460..6bba41b7d5 100644 --- a/src/Umbraco.Core/HealthCheck/Checks/Security/HttpsCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Security/HttpsCheck.cs @@ -3,15 +3,14 @@ using System.Collections.Generic; using System.Net; using System.Security.Cryptography.X509Certificates; using Microsoft.Extensions.Logging; -using Umbraco.Core; -using Umbraco.Core.Configuration; -using Umbraco.Core.IO; using Umbraco.Core.Services; -using Umbraco.Web.HealthCheck.Checks.Config; using Umbraco.Core.Configuration.Models; using Microsoft.Extensions.Options; +using Umbraco.Core.Configuration.HealthChecks; +using Umbraco.Core.IO; +using Umbraco.Web; -namespace Umbraco.Web.HealthCheck.Checks.Security +namespace Umbraco.Core.HealthCheck.Checks.Security { [HealthCheck( "EB66BB3B-1BCD-4314-9531-9DA2C1D6D9A7", @@ -21,22 +20,20 @@ namespace Umbraco.Web.HealthCheck.Checks.Security public class HttpsCheck : HealthCheck { private readonly ILocalizedTextService _textService; - private readonly GlobalSettings _globalSettings; - private readonly IIOHelper _ioHelper; + private readonly IOptionsMonitor _globalSettings; private readonly IRequestAccessor _requestAccessor; - private readonly ILogger _logger; - + private readonly ILogger _logger; private const string FixHttpsSettingAction = "fixHttpsSetting"; + string itemPath => Constants.Configuration.ConfigGlobalUseHttps; public HttpsCheck(ILocalizedTextService textService, - IOptions globalSettings, + IOptionsMonitor globalSettings, IIOHelper ioHelper, IRequestAccessor requestAccessor, - ILogger logger) + ILogger logger) { _textService = textService; - _globalSettings = globalSettings.Value; - _ioHelper = ioHelper; + _globalSettings = globalSettings; _requestAccessor = requestAccessor; _logger = logger; } @@ -75,7 +72,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Security // Attempt to access the site over HTTPS to see if it HTTPS is supported // and a valid certificate has been configured var url = _requestAccessor.GetApplicationUrl().ToString().Replace("http:", "https:"); - var request = (HttpWebRequest) WebRequest.Create(url); + var request = (HttpWebRequest)WebRequest.Create(url); request.Method = "HEAD"; try @@ -119,8 +116,8 @@ namespace Umbraco.Web.HealthCheck.Checks.Security if (exception != null) { message = exception.Status == WebExceptionStatus.TrustFailure - ? _textService.Localize("healthcheck/httpsCheckInvalidCertificate", new [] { exception.Message }) - : _textService.Localize("healthcheck/healthCheckInvalidUrl", new [] { url, exception.Message }); + ? _textService.Localize("healthcheck/httpsCheckInvalidCertificate", new[] { exception.Message }) + : _textService.Localize("healthcheck/healthCheckInvalidUrl", new[] { url, exception.Message }); } else { @@ -132,33 +129,31 @@ namespace Umbraco.Web.HealthCheck.Checks.Security var actions = new List(); - return - new HealthCheckStatus(message) - { - ResultType = result, - Actions = actions - }; + return new HealthCheckStatus(message) + { + ResultType = result, + Actions = actions + }; } private HealthCheckStatus CheckIfCurrentSchemeIsHttps() { - var uri = _requestAccessor.GetApplicationUrl(); + var uri = _requestAccessor.GetApplicationUrl(); var success = uri.Scheme == "https"; var actions = new List(); - return - new HealthCheckStatus(_textService.Localize("healthcheck/httpsCheckIsCurrentSchemeHttps", new[] { success ? string.Empty : "not" })) - { - ResultType = success ? StatusResultType.Success : StatusResultType.Error, - Actions = actions - }; + return new HealthCheckStatus(_textService.Localize("healthcheck/httpsCheckIsCurrentSchemeHttps", new[] { success ? string.Empty : "not" })) + { + ResultType = success ? StatusResultType.Success : StatusResultType.Error, + Actions = actions + }; } private HealthCheckStatus CheckHttpsConfigurationSetting() { - var httpsSettingEnabled = _globalSettings.UseHttps; - var uri = _requestAccessor.GetApplicationUrl(); + bool httpsSettingEnabled = _globalSettings.CurrentValue.UseHttps; + Uri uri = _requestAccessor.GetApplicationUrl(); var actions = new List(); string resultMessage; @@ -171,46 +166,34 @@ namespace Umbraco.Web.HealthCheck.Checks.Security else { if (httpsSettingEnabled == false) + { actions.Add(new HealthCheckAction(FixHttpsSettingAction, Id) { Name = _textService.Localize("healthcheck/httpsCheckEnableHttpsButton"), Description = _textService.Localize("healthcheck/httpsCheckEnableHttpsDescription") }); + } resultMessage = _textService.Localize("healthcheck/httpsCheckConfigurationCheckResult", - new[] {httpsSettingEnabled.ToString(), httpsSettingEnabled ? string.Empty : "not"}); - resultType = httpsSettingEnabled ? StatusResultType.Success: StatusResultType.Error; + new[] { httpsSettingEnabled.ToString(), httpsSettingEnabled ? string.Empty : "not" }); + resultType = httpsSettingEnabled ? StatusResultType.Success : StatusResultType.Error; } - return - new HealthCheckStatus(resultMessage) - { - ResultType = resultType, - Actions = actions - }; + return new HealthCheckStatus(resultMessage) + { + ResultType = resultType, + Actions = actions + }; } private HealthCheckStatus FixHttpsSetting() { - var configFile = _ioHelper.MapPath("~/Web.config"); - const string xPath = "/configuration/appSettings/add[@key='Umbraco.Core.UseHttps']/@value"; - var configurationService = new ConfigurationService(configFile, xPath, _textService, _logger); - var updateConfigFile = configurationService.UpdateConfigFile("true"); + //TODO: return message instead of actual fix - if (updateConfigFile.Success) + return new HealthCheckStatus(_textService.Localize("healthcheck/httpsCheckEnableHttpsSuccess")) { - return - new HealthCheckStatus(_textService.Localize("healthcheck/httpsCheckEnableHttpsSuccess")) - { - ResultType = StatusResultType.Success - }; - } - - return - new HealthCheckStatus(_textService.Localize("healthcheck/httpsCheckEnableHttpsError", new [] { updateConfigFile.Result })) - { - ResultType = StatusResultType.Error - }; + ResultType = StatusResultType.Success + }; } } } diff --git a/src/Umbraco.Core/HealthCheck/Checks/Security/NoSniffCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Security/NoSniffCheck.cs index 0b6fb9e347..c392842049 100644 --- a/src/Umbraco.Core/HealthCheck/Checks/Security/NoSniffCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Security/NoSniffCheck.cs @@ -1,8 +1,7 @@ -using Umbraco.Core; -using Umbraco.Core.IO; -using Umbraco.Core.Services; +using Umbraco.Core.Services; +using Umbraco.Web; -namespace Umbraco.Web.HealthCheck.Checks.Security +namespace Umbraco.Core.HealthCheck.Checks.Security { [HealthCheck( "1CF27DB3-EFC0-41D7-A1BB-EA912064E071", @@ -11,8 +10,8 @@ namespace Umbraco.Web.HealthCheck.Checks.Security Group = "Security")] public class NoSniffCheck : BaseHttpHeaderCheck { - public NoSniffCheck(IRequestAccessor requestAccessor, ILocalizedTextService textService, IIOHelper ioHelper) - : base(requestAccessor, textService, "X-Content-Type-Options", "nosniff", "noSniff", false, ioHelper) + public NoSniffCheck(IRequestAccessor requestAccessor, ILocalizedTextService textService) + : base(requestAccessor, textService, "X-Content-Type-Options", "nosniff", "noSniff", false) { } } diff --git a/src/Umbraco.Core/HealthCheck/Checks/Security/XssProtectionCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Security/XssProtectionCheck.cs index 7d658e2082..a5f0f28f22 100644 --- a/src/Umbraco.Core/HealthCheck/Checks/Security/XssProtectionCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Security/XssProtectionCheck.cs @@ -1,8 +1,7 @@ -using Umbraco.Core; -using Umbraco.Core.IO; -using Umbraco.Core.Services; +using Umbraco.Core.Services; +using Umbraco.Web; -namespace Umbraco.Web.HealthCheck.Checks.Security +namespace Umbraco.Core.HealthCheck.Checks.Security { [HealthCheck( "F4D2B02E-28C5-4999-8463-05759FA15C3A", @@ -16,8 +15,8 @@ namespace Umbraco.Web.HealthCheck.Checks.Security // and the blog post of Troy Hunt (https://www.troyhunt.com/understanding-http-strict-transport/) // If you want do to it perfectly, you have to submit it https://hstspreload.appspot.com/, // but then you should include subdomains and I wouldn't suggest to do that for Umbraco-sites. - public XssProtectionCheck(IRequestAccessor requestAccessor,ILocalizedTextService textService, IIOHelper ioHelper) - : base(requestAccessor, textService, "X-XSS-Protection", "1; mode=block", "xssProtection", true, ioHelper) + public XssProtectionCheck(IRequestAccessor requestAccessor,ILocalizedTextService textService) + : base(requestAccessor, textService, "X-XSS-Protection", "1; mode=block", "xssProtection", true) { } } diff --git a/src/Umbraco.Core/HealthCheck/Checks/Services/SmtpCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Services/SmtpCheck.cs index 77b1201ef6..9e1a6f84af 100644 --- a/src/Umbraco.Core/HealthCheck/Checks/Services/SmtpCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Services/SmtpCheck.cs @@ -3,12 +3,10 @@ using System.Collections.Generic; using System.IO; using System.Net.Sockets; using Microsoft.Extensions.Options; -using Umbraco.Core; -using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Services; -namespace Umbraco.Web.HealthCheck.Checks.Services +namespace Umbraco.Core.HealthCheck.Checks.Services { [HealthCheck( "1B5D221B-CE99-4193-97CB-5F3261EC73DF", @@ -18,12 +16,12 @@ namespace Umbraco.Web.HealthCheck.Checks.Services public class SmtpCheck : HealthCheck { private readonly ILocalizedTextService _textService; - private readonly GlobalSettings _globalSettings; + private readonly IOptionsMonitor _globalSettings; - public SmtpCheck(ILocalizedTextService textService, IOptions globalSettings) + public SmtpCheck(ILocalizedTextService textService, IOptionsMonitor globalSettings) { _textService = textService; - _globalSettings = globalSettings.Value; + _globalSettings = globalSettings; } /// @@ -50,7 +48,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Services { var success = false; - var smtpSettings = _globalSettings.Smtp; + var smtpSettings = _globalSettings.CurrentValue.Smtp; string message; if (smtpSettings == null) diff --git a/src/Umbraco.Core/Configuration/HealthChecks/ConfigurationServiceResult.cs b/src/Umbraco.Core/HealthCheck/ConfigurationServiceResult.cs similarity index 73% rename from src/Umbraco.Core/Configuration/HealthChecks/ConfigurationServiceResult.cs rename to src/Umbraco.Core/HealthCheck/ConfigurationServiceResult.cs index 3b1400da5b..b4940f927a 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/ConfigurationServiceResult.cs +++ b/src/Umbraco.Core/HealthCheck/ConfigurationServiceResult.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Web.HealthCheck.Checks.Config +namespace Umbraco.Core.HealthCheck { public class ConfigurationServiceResult { diff --git a/src/Umbraco.Core/HealthCheck/HealthCheck.cs b/src/Umbraco.Core/HealthCheck/HealthCheck.cs index 73defd2fef..89a1f41f4d 100644 --- a/src/Umbraco.Core/HealthCheck/HealthCheck.cs +++ b/src/Umbraco.Core/HealthCheck/HealthCheck.cs @@ -1,24 +1,25 @@ using System; using System.Collections.Generic; using System.Runtime.Serialization; -using Umbraco.Core; using Umbraco.Core.Composing; -namespace Umbraco.Web.HealthCheck +namespace Umbraco.Core.HealthCheck { /// - /// Provides a base class for health checks. + /// Provides a base class for health checks, filling in the healthcheck metadata on construction /// [DataContract(Name = "healthCheck", Namespace = "")] public abstract class HealthCheck : IDiscoverable { protected HealthCheck() { - //Fill in the metadata - var thisType = GetType(); - var meta = thisType.GetCustomAttribute(false); + Type thisType = GetType(); + HealthCheckAttribute meta = thisType.GetCustomAttribute(false); if (meta == null) - throw new InvalidOperationException($"The health check {thisType} requires a {typeof (HealthCheckAttribute)}"); + { + throw new InvalidOperationException($"The health check {thisType} requires a {typeof(HealthCheckAttribute)}"); + } + Name = meta.Name; Description = meta.Description; Group = meta.Group; @@ -49,7 +50,5 @@ namespace Umbraco.Web.HealthCheck /// /// public abstract HealthCheckStatus ExecuteAction(HealthCheckAction action); - - // TODO: What else? } } diff --git a/src/Umbraco.Core/HealthCheck/HealthCheckAction.cs b/src/Umbraco.Core/HealthCheck/HealthCheckAction.cs index b64eb6746a..e1771a4262 100644 --- a/src/Umbraco.Core/HealthCheck/HealthCheckAction.cs +++ b/src/Umbraco.Core/HealthCheck/HealthCheckAction.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Runtime.Serialization; -namespace Umbraco.Web.HealthCheck +namespace Umbraco.Core.HealthCheck { [DataContract(Name = "healthCheckAction", Namespace = "")] public class HealthCheckAction diff --git a/src/Umbraco.Core/HealthCheck/HealthCheckAttribute.cs b/src/Umbraco.Core/HealthCheck/HealthCheckAttribute.cs index fe206f3186..bd8c10f899 100644 --- a/src/Umbraco.Core/HealthCheck/HealthCheckAttribute.cs +++ b/src/Umbraco.Core/HealthCheck/HealthCheckAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace Umbraco.Web.HealthCheck +namespace Umbraco.Core.HealthCheck { /// /// Metadata attribute for Health checks diff --git a/src/Umbraco.Core/HealthCheck/HealthCheckCollection.cs b/src/Umbraco.Core/HealthCheck/HealthCheckCollection.cs index 6de442b765..fc8d5dff25 100644 --- a/src/Umbraco.Core/HealthCheck/HealthCheckCollection.cs +++ b/src/Umbraco.Core/HealthCheck/HealthCheckCollection.cs @@ -1,11 +1,11 @@ using System.Collections.Generic; using Umbraco.Core.Composing; -namespace Umbraco.Web.HealthCheck +namespace Umbraco.Core.HealthCheck { - public class HealthCheckCollection : BuilderCollectionBase + public class HealthCheckCollection : BuilderCollectionBase { - public HealthCheckCollection(IEnumerable items) + public HealthCheckCollection(IEnumerable items) : base(items) { } } diff --git a/src/Umbraco.Core/HealthCheck/HealthCheckGroup.cs b/src/Umbraco.Core/HealthCheck/HealthCheckGroup.cs index f01c65f854..2cd1040896 100644 --- a/src/Umbraco.Core/HealthCheck/HealthCheckGroup.cs +++ b/src/Umbraco.Core/HealthCheck/HealthCheckGroup.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Runtime.Serialization; -namespace Umbraco.Web.HealthCheck +namespace Umbraco.Core.HealthCheck { [DataContract(Name = "healthCheckGroup", Namespace = "")] public class HealthCheckGroup diff --git a/src/Umbraco.Core/HealthCheck/HealthCheckNotificationMethodAttribute.cs b/src/Umbraco.Core/HealthCheck/HealthCheckNotificationMethodAttribute.cs index d9da271d58..f78df14942 100644 --- a/src/Umbraco.Core/HealthCheck/HealthCheckNotificationMethodAttribute.cs +++ b/src/Umbraco.Core/HealthCheck/HealthCheckNotificationMethodAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace Umbraco.Web.HealthCheck +namespace Umbraco.Core.HealthCheck { /// /// Metadata attribute for health check notification methods diff --git a/src/Umbraco.Core/Configuration/HealthChecks/HealthCheckNotificationVerbosity.cs b/src/Umbraco.Core/HealthCheck/HealthCheckNotificationVerbosity.cs similarity index 52% rename from src/Umbraco.Core/Configuration/HealthChecks/HealthCheckNotificationVerbosity.cs rename to src/Umbraco.Core/HealthCheck/HealthCheckNotificationVerbosity.cs index 95e5ca8e03..74cd4eb93b 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/HealthCheckNotificationVerbosity.cs +++ b/src/Umbraco.Core/HealthCheck/HealthCheckNotificationVerbosity.cs @@ -1,6 +1,4 @@ -using System.Runtime.Serialization; - -namespace Umbraco.Core.Configuration.HealthChecks +namespace Umbraco.Core.HealthCheck { public enum HealthCheckNotificationVerbosity { diff --git a/src/Umbraco.Core/HealthCheck/HealthCheckStatus.cs b/src/Umbraco.Core/HealthCheck/HealthCheckStatus.cs index 245267ff8e..2eb873603f 100644 --- a/src/Umbraco.Core/HealthCheck/HealthCheckStatus.cs +++ b/src/Umbraco.Core/HealthCheck/HealthCheckStatus.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Runtime.Serialization; -namespace Umbraco.Web.HealthCheck +namespace Umbraco.Core.HealthCheck { /// /// The status returned for a health check when it performs it check diff --git a/src/Umbraco.Core/HealthCheck/HeathCheckCollectionBuilder.cs b/src/Umbraco.Core/HealthCheck/HeathCheckCollectionBuilder.cs index e616ba49ae..0894cb1912 100644 --- a/src/Umbraco.Core/HealthCheck/HeathCheckCollectionBuilder.cs +++ b/src/Umbraco.Core/HealthCheck/HeathCheckCollectionBuilder.cs @@ -1,6 +1,6 @@ using Umbraco.Core.Composing; -namespace Umbraco.Web.HealthCheck +namespace Umbraco.Core.HealthCheck { public class HealthCheckCollectionBuilder : LazyCollectionBuilderBase { diff --git a/src/Umbraco.Core/HealthCheck/IConfigurationService.cs b/src/Umbraco.Core/HealthCheck/IConfigurationService.cs new file mode 100644 index 0000000000..dc513bb765 --- /dev/null +++ b/src/Umbraco.Core/HealthCheck/IConfigurationService.cs @@ -0,0 +1,7 @@ +namespace Umbraco.Core.HealthCheck +{ + public interface IConfigurationService + { + ConfigurationServiceResult UpdateConfigFile(string value, string itemPath); + } +} diff --git a/src/Umbraco.Core/Configuration/HealthChecks/INotificationMethod.cs b/src/Umbraco.Core/HealthCheck/INotificationMethod.cs similarity index 86% rename from src/Umbraco.Core/Configuration/HealthChecks/INotificationMethod.cs rename to src/Umbraco.Core/HealthCheck/INotificationMethod.cs index 84bf55e160..9c4ec70cfe 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/INotificationMethod.cs +++ b/src/Umbraco.Core/HealthCheck/INotificationMethod.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Umbraco.Core.Configuration.HealthChecks +namespace Umbraco.Core.HealthCheck { public interface INotificationMethod { diff --git a/src/Umbraco.Core/Configuration/HealthChecks/INotificationMethodSettings.cs b/src/Umbraco.Core/HealthCheck/INotificationMethodSettings.cs similarity index 69% rename from src/Umbraco.Core/Configuration/HealthChecks/INotificationMethodSettings.cs rename to src/Umbraco.Core/HealthCheck/INotificationMethodSettings.cs index e41c82b393..01ad667d94 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/INotificationMethodSettings.cs +++ b/src/Umbraco.Core/HealthCheck/INotificationMethodSettings.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core.Configuration.HealthChecks +namespace Umbraco.Core.HealthCheck { public interface INotificationMethodSettings { diff --git a/src/Umbraco.Core/HealthCheck/StatusResultType.cs b/src/Umbraco.Core/HealthCheck/StatusResultType.cs index c6bd50f247..3f2c392933 100644 --- a/src/Umbraco.Core/HealthCheck/StatusResultType.cs +++ b/src/Umbraco.Core/HealthCheck/StatusResultType.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Web.HealthCheck +namespace Umbraco.Core.HealthCheck { public enum StatusResultType { diff --git a/src/Umbraco.Core/Configuration/HealthChecks/ValueComparisonType.cs b/src/Umbraco.Core/HealthCheck/ValueComparisonType.cs similarity index 65% rename from src/Umbraco.Core/Configuration/HealthChecks/ValueComparisonType.cs rename to src/Umbraco.Core/HealthCheck/ValueComparisonType.cs index 8df40da9f9..c5dd6517a8 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/ValueComparisonType.cs +++ b/src/Umbraco.Core/HealthCheck/ValueComparisonType.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Web.HealthCheck.Checks.Config +namespace Umbraco.Core.HealthCheck { public enum ValueComparisonType { diff --git a/src/Umbraco.Core/IEmailSender.cs b/src/Umbraco.Core/IEmailSender.cs index 748b8e6b0a..aab944e04d 100644 --- a/src/Umbraco.Core/IEmailSender.cs +++ b/src/Umbraco.Core/IEmailSender.cs @@ -1,5 +1,5 @@ -using System.Net.Mail; -using System.Threading.Tasks; +using System.Threading.Tasks; +using Umbraco.Core.Models; namespace Umbraco.Core { @@ -8,7 +8,6 @@ namespace Umbraco.Core /// public interface IEmailSender { - // TODO: This would be better if MailMessage was our own abstraction! - Task SendAsync(MailMessage message); + Task SendAsync(EmailMessage message); } } diff --git a/src/Umbraco.Core/IO/FileSystems.cs b/src/Umbraco.Core/IO/FileSystems.cs index e5c8caffe7..485e6b6446 100644 --- a/src/Umbraco.Core/IO/FileSystems.cs +++ b/src/Umbraco.Core/IO/FileSystems.cs @@ -282,7 +282,7 @@ namespace Umbraco.Core.IO { lock (_shadowLocker) { - var wrapper = new ShadowWrapper(filesystem, _ioHelper, _hostingEnvironment, _loggerFactory, shadowPath, IsScoped); + var wrapper = new ShadowWrapper(filesystem, _ioHelper, _hostingEnvironment, _loggerFactory, shadowPath,() => IsScoped()); if (_shadowCurrentId != null) wrapper.Shadow(_shadowCurrentId); _shadowWrappers.Add(wrapper); diff --git a/src/Umbraco.Core/IO/IOHelper.cs b/src/Umbraco.Core/IO/IOHelper.cs index 118b528869..b3ca956733 100644 --- a/src/Umbraco.Core/IO/IOHelper.cs +++ b/src/Umbraco.Core/IO/IOHelper.cs @@ -122,7 +122,7 @@ namespace Umbraco.Core.IO var mappedRoot = MapPath(_hostingEnvironment.ApplicationVirtualPath); if (filePath.StartsWith(mappedRoot) == false) - filePath = MapPath(filePath); + filePath = _hostingEnvironment.MapPathContentRoot(filePath); // yes we can (see above) //// don't trust what we get, it may contain relative segments @@ -132,7 +132,7 @@ namespace Umbraco.Core.IO { var validDir = dir; if (validDir.StartsWith(mappedRoot) == false) - validDir = MapPath(validDir); + validDir = _hostingEnvironment.MapPathContentRoot(validDir); if (PathStartsWith(filePath, validDir, Path.DirectorySeparatorChar)) return true; diff --git a/src/Umbraco.Core/IO/PhysicalFileSystem.cs b/src/Umbraco.Core/IO/PhysicalFileSystem.cs index 04e3df6ab3..6ed866754d 100644 --- a/src/Umbraco.Core/IO/PhysicalFileSystem.cs +++ b/src/Umbraco.Core/IO/PhysicalFileSystem.cs @@ -10,7 +10,8 @@ using Umbraco.Core.Hosting; namespace Umbraco.Core.IO { - public class PhysicalFileSystem : IFileSystem + public interface IPhysicalFileSystem : IFileSystem {} + public class PhysicalFileSystem : IPhysicalFileSystem { private readonly IIOHelper _ioHelper; private readonly ILogger _logger; @@ -56,7 +57,6 @@ namespace Umbraco.Core.IO if (string.IsNullOrEmpty(rootUrl)) throw new ArgumentException("Value can't be empty.", nameof(rootUrl)); if (rootPath.StartsWith("~/")) throw new ArgumentException("Value can't be a virtual path and start with '~/'.", nameof(rootPath)); - // rootPath should be... rooted, as in, it's a root path! if (Path.IsPathRooted(rootPath) == false) { @@ -65,6 +65,9 @@ namespace Umbraco.Core.IO rootPath = Path.Combine(localRoot, rootPath); } + // clean up root path + rootPath = Path.GetFullPath(rootPath); + _rootPath = EnsureDirectorySeparatorChar(rootPath).TrimEnd(Path.DirectorySeparatorChar); _rootPathFwd = EnsureUrlSeparatorChar(_rootPath); _rootUrl = EnsureUrlSeparatorChar(rootUrl).TrimEnd('/'); @@ -328,7 +331,7 @@ namespace Umbraco.Core.IO // nothing prevents us to reach the file, security-wise, yet it is outside // this filesystem's root - throw - throw new UnauthorizedAccessException("File '" + opath + "' is outside this filesystem's root."); + throw new UnauthorizedAccessException($"File original: [{opath}] full: [{path}] is outside this filesystem's root."); } /// diff --git a/src/Umbraco.Core/IO/SupportingFileSystems.cs b/src/Umbraco.Core/IO/SupportingFileSystems.cs deleted file mode 100644 index 43ac2ba85a..0000000000 --- a/src/Umbraco.Core/IO/SupportingFileSystems.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Umbraco.Core.Composing; - -namespace Umbraco.Core.IO -{ - public class SupportingFileSystems : TargetedServiceFactory - { - public SupportingFileSystems(IFactory factory) - : base(factory) - { } - } -} diff --git a/src/Umbraco.Core/Models/EmailMessage.cs b/src/Umbraco.Core/Models/EmailMessage.cs new file mode 100644 index 0000000000..11483e1b20 --- /dev/null +++ b/src/Umbraco.Core/Models/EmailMessage.cs @@ -0,0 +1,35 @@ +using System; + +namespace Umbraco.Core.Models +{ + public class EmailMessage + { + public string From { get; } + public string To { get; } + public string Subject { get; } + public string Body { get; } + public bool IsBodyHtml { get; } + + public EmailMessage(string from, string to, string subject, string body, bool isBodyHtml) + { + if (from == null) throw new ArgumentNullException(nameof(from)); + if (from.Length == 0) throw new ArgumentException("Value cannot be empty.", nameof(from)); + + if (to == null) throw new ArgumentNullException(nameof(to)); + if (to.Length == 0) throw new ArgumentException("Value cannot be empty.", nameof(to)); + + if (subject == null) throw new ArgumentNullException(nameof(subject)); + if (subject.Length == 0) throw new ArgumentException("Value cannot be empty.", nameof(subject)); + + if (body == null) throw new ArgumentNullException(nameof(body)); + if (body.Length == 0) throw new ArgumentException("Value cannot be empty.", nameof(body)); + + From = from; + To = to; + Subject = subject; + Body = body; + + IsBodyHtml = isBodyHtml; + } + } +} diff --git a/src/Umbraco.Core/RegisterExtensions.cs b/src/Umbraco.Core/RegisterExtensions.cs index 69e092878e..67f256a26f 100644 --- a/src/Umbraco.Core/RegisterExtensions.cs +++ b/src/Umbraco.Core/RegisterExtensions.cs @@ -13,13 +13,6 @@ namespace Umbraco.Core public static void Register(this IRegister register, Lifetime lifetime = Lifetime.Transient) => register.Register(typeof(TService), typeof(TImplementing), lifetime); - /// - /// Registers a service with an implementation type, for a target. - /// - public static void RegisterFor(this IRegister register, Lifetime lifetime = Lifetime.Transient) - where TService : class - => register.RegisterFor(typeof(TImplementing), lifetime); - /// /// Registers a service as its own implementation. /// @@ -33,12 +26,5 @@ namespace Umbraco.Core public static void Register(this IRegister register, TService instance) where TService : class => register.Register(typeof(TService), instance); - - /// - /// Registers a base type for auto-registration. - /// - public static void RegisterAuto(this IRegister register) - where TServiceBase : class - => register.RegisterAuto(typeof(TServiceBase)); } } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 07dea8d299..2b3efc9349 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -15,6 +15,7 @@ + diff --git a/src/Umbraco.Infrastructure/BackOffice/BackOfficeIdentityBuilder.cs b/src/Umbraco.Infrastructure/BackOffice/BackOfficeIdentityBuilder.cs new file mode 100644 index 0000000000..5bae03cad6 --- /dev/null +++ b/src/Umbraco.Infrastructure/BackOffice/BackOfficeIdentityBuilder.cs @@ -0,0 +1,39 @@ +using System; +using System.Reflection; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core.BackOffice; + +namespace Umbraco.Infrastructure.BackOffice +{ + public class BackOfficeIdentityBuilder : IdentityBuilder + { + public BackOfficeIdentityBuilder(IServiceCollection services) : base(typeof(BackOfficeIdentityUser), services) + { + } + + public BackOfficeIdentityBuilder(Type role, IServiceCollection services) : base(typeof(BackOfficeIdentityUser), role, services) + { + } + + /// + /// Adds a token provider for the . + /// + /// The name of the provider to add. + /// The type of the to add. + /// The current instance. + public override IdentityBuilder AddTokenProvider(string providerName, Type provider) + { + if (!typeof(IUserTwoFactorTokenProvider<>).MakeGenericType(UserType).GetTypeInfo().IsAssignableFrom(provider.GetTypeInfo())) + { + throw new InvalidOperationException($"Invalid Type for TokenProvider: {provider.FullName}"); + } + Services.Configure(options => + { + options.Tokens.ProviderMap[providerName] = new TokenProviderDescriptor(provider); + }); + Services.AddTransient(provider); + return this; + } + } +} diff --git a/src/Umbraco.Web/Compose/AuditEventsComponent.cs b/src/Umbraco.Infrastructure/Compose/AuditEventsComponent.cs similarity index 98% rename from src/Umbraco.Web/Compose/AuditEventsComponent.cs rename to src/Umbraco.Infrastructure/Compose/AuditEventsComponent.cs index 4b5669a33f..c085db2496 100644 --- a/src/Umbraco.Web/Compose/AuditEventsComponent.cs +++ b/src/Umbraco.Infrastructure/Compose/AuditEventsComponent.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Text; using System.Threading; +using Microsoft.Extensions.Options; using Umbraco.Core.Composing; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Events; @@ -23,13 +24,13 @@ namespace Umbraco.Core.Compose private readonly IIpResolver _ipResolver; private readonly GlobalSettings _globalSettings; - public AuditEventsComponent(IAuditService auditService, IUserService userService, IEntityService entityService, IIpResolver ipResolver, GlobalSettings globalSettings) + public AuditEventsComponent(IAuditService auditService, IUserService userService, IEntityService entityService, IIpResolver ipResolver, IOptions globalSettings) { _auditService = auditService; _userService = userService; _entityService = entityService; _ipResolver = ipResolver; - _globalSettings = globalSettings; + _globalSettings = globalSettings.Value; } public void Initialize() diff --git a/src/Umbraco.Web/Compose/AuditEventsComposer.cs b/src/Umbraco.Infrastructure/Compose/AuditEventsComposer.cs similarity index 100% rename from src/Umbraco.Web/Compose/AuditEventsComposer.cs rename to src/Umbraco.Infrastructure/Compose/AuditEventsComposer.cs diff --git a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/FileSystems.cs b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/FileSystems.cs index d6b8288b88..adba706d13 100644 --- a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/FileSystems.cs +++ b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/FileSystems.cs @@ -1,10 +1,10 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.IO.MediaPathSchemes; +using Umbraco.Core.Strings; namespace Umbraco.Core.Composing.CompositionExtensions { @@ -14,50 +14,9 @@ namespace Umbraco.Core.Composing.CompositionExtensions * HOW TO REPLACE THE MEDIA UNDERLYING FILESYSTEM * ---------------------------------------------- * - * Create a component and use it to modify the composition by adding something like: + * composition.RegisterUnique(factoryMethod); * - * composition.RegisterUniqueFor(...); - * - * and register whatever supporting filesystem you like. - * - * - * HOW TO IMPLEMENT MY OWN FILESYSTEM - * ---------------------------------- - * - * Create your filesystem class: - * - * public class MyFileSystem : FileSystemWrapper - * { - * public MyFileSystem(IFileSystem innerFileSystem) - * : base(innerFileSystem) - * { } - * } - * - * The ctor can have more parameters, that will be resolved by the container. - * - * Register your filesystem, in a component: - * - * composition.RegisterFileSystem(); - * - * Register the underlying filesystem: - * - * composition.RegisterUniqueFor(...); - * - * And that's it, you can inject MyFileSystem wherever it's needed. - * - * - * You can also declare a filesystem interface: - * - * public interface IMyFileSystem : IFileSystem - * { } - * - * Make the class implement the interface, then - * register your filesystem, in a component: - * - * composition.RegisterFileSystem(); - * composition.RegisterUniqueFor(...); - * - * And that's it, you can inject IMyFileSystem wherever it's needed. + * composition.RegisterUnique(); * * * WHAT IS SHADOWING @@ -85,16 +44,8 @@ namespace Umbraco.Core.Composing.CompositionExtensions // register the scheme for media paths composition.RegisterUnique(); - // register the IMediaFileSystem implementation - composition.RegisterFileSystem(); - - // register the supporting filesystems provider - composition.Register(factory => new SupportingFileSystems(factory), Lifetime.Singleton); - - // register the IFileSystem supporting the IMediaFileSystem - // THIS IS THE ONLY THING THAT NEEDS TO CHANGE, IN ORDER TO REPLACE THE UNDERLYING FILESYSTEM - // and, SupportingFileSystem.For() returns the underlying filesystem - composition.SetMediaFileSystem(factory => + // register the default IMediaFileSystem implementation + composition.RegisterUnique(factory => { var ioHelper = factory.GetInstance(); var hostingEnvironment = factory.GetInstance(); @@ -103,7 +54,10 @@ namespace Umbraco.Core.Composing.CompositionExtensions var rootPath = hostingEnvironment.MapPathWebRoot(globalSettings.UmbracoMediaPath); var rootUrl = hostingEnvironment.ToAbsolute(globalSettings.UmbracoMediaPath); - return new PhysicalFileSystem(ioHelper, hostingEnvironment, logger, rootPath, rootUrl); + var inner = new PhysicalFileSystem(ioHelper, hostingEnvironment, logger, rootPath, rootUrl); + + var fileSystems = factory.GetInstance(); + return fileSystems.GetFileSystem(inner); }); return composition; diff --git a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Installer.cs b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Installer.cs index 707fcdbdc1..d49d1b4783 100644 --- a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Installer.cs +++ b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Installer.cs @@ -12,19 +12,19 @@ namespace Umbraco.Web.Composing.CompositionExtensions { // register the installer steps - composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); + composition.Register(Lifetime.Scope); + composition.Register(Lifetime.Scope); + composition.Register(Lifetime.Scope); + composition.Register(Lifetime.Scope); + composition.Register(Lifetime.Scope); + composition.Register(Lifetime.Scope); // TODO: Add these back once we have a compatible Starter kit - // composition.Register(Lifetime.Scope); - // composition.Register(Lifetime.Scope); - // composition.Register(Lifetime.Scope); + // composition.Register(Lifetime.Scope); + // composition.Register(Lifetime.Scope); + // composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); + composition.Register(Lifetime.Scope); composition.Register(); composition.RegisterUnique(); diff --git a/src/Umbraco.Infrastructure/Composing/HostBuilderExtensions.cs b/src/Umbraco.Infrastructure/Composing/HostBuilderExtensions.cs index ad7c75b94f..7c17a8a338 100644 --- a/src/Umbraco.Infrastructure/Composing/HostBuilderExtensions.cs +++ b/src/Umbraco.Infrastructure/Composing/HostBuilderExtensions.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Hosting; -using Serilog; namespace Umbraco.Core.Composing { @@ -15,17 +14,7 @@ namespace Umbraco.Core.Composing /// public static IHostBuilder UseUmbraco(this IHostBuilder builder) { - return builder - .UseUmbraco(new UmbracoServiceProviderFactory()); + return builder; } - - /// - /// Assigns a custom service provider factory to use Umbraco's container - /// - /// - /// - /// - public static IHostBuilder UseUmbraco(this IHostBuilder builder, UmbracoServiceProviderFactory umbracoServiceProviderFactory) - => builder.UseServiceProviderFactory(umbracoServiceProviderFactory); } } diff --git a/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs b/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs index a6db0b7b2b..3537230c2b 100644 --- a/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs +++ b/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs @@ -183,32 +183,6 @@ namespace Umbraco.Core.Composing.LightInject public void Register(Type serviceType, object instance) => Container.RegisterInstance(serviceType, instance); - /// - public void RegisterFor(Lifetime lifetime = Lifetime.Transient) - where TService : class - => RegisterFor(typeof(TService), lifetime); - - /// - public void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient) - where TService : class - { - // note that there can only be one implementation or instance registered "for" a service - Container.Register(typeof(TService), implementingType, GetTargetedServiceName(), GetLifetime(lifetime)); - } - - /// - public void RegisterFor(Func factory, Lifetime lifetime = Lifetime.Transient) - where TService : class - { - // note that there can only be one implementation or instance registered "for" a service - Container.Register(f => factory(this), GetTargetedServiceName(), GetLifetime(lifetime)); - } - - /// - public void RegisterFor(TService instance) - where TService : class - => Container.RegisterInstance(typeof(TService), instance, GetTargetedServiceName()); - private ILifetime GetLifetime(Lifetime lifetime) { switch (lifetime) diff --git a/src/Umbraco.Infrastructure/Composing/ServiceCollectionRegistryAdapter.cs b/src/Umbraco.Infrastructure/Composing/ServiceCollectionRegistryAdapter.cs new file mode 100644 index 0000000000..d0ff384cb1 --- /dev/null +++ b/src/Umbraco.Infrastructure/Composing/ServiceCollectionRegistryAdapter.cs @@ -0,0 +1,92 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core.Composing; + +namespace Umbraco.Infrastructure.Composing +{ + public class ServiceCollectionRegistryAdapter : IRegister + { + private readonly IServiceCollection _services; + + public ServiceCollectionRegistryAdapter(IServiceCollection services) + { + _services = services ?? throw new ArgumentNullException(nameof(services)); + _services.AddTransient(typeof(Lazy<>), typeof(LazyResolve<>)); + } + + public void Register(Type serviceType, Lifetime lifetime = Lifetime.Transient) + { + switch (lifetime) + { + case Lifetime.Request: + case Lifetime.Scope: + _services.AddScoped(serviceType); + break; + case Lifetime.Transient: + _services.AddTransient(serviceType); + break; + case Lifetime.Singleton: + _services.AddSingleton(serviceType); + break; + default: + throw new NotImplementedException($"Unhandled Lifetime: {lifetime}"); + } + } + + public void Register(Type serviceType, Type implementingType, Lifetime lifetime = Lifetime.Transient) + { + switch (lifetime) + { + case Lifetime.Request: + case Lifetime.Scope: + _services.AddScoped(serviceType, implementingType); + break; + case Lifetime.Transient: + _services.AddTransient(serviceType, implementingType); + break; + case Lifetime.Singleton: + _services.AddSingleton(serviceType, implementingType); + break; + default: + throw new NotImplementedException($"Unhandled Lifetime: {lifetime}"); + } + } + + public void Register(Func factory, Lifetime lifetime = Lifetime.Transient) where TService : class + { + switch (lifetime) + { + case Lifetime.Request: + case Lifetime.Scope: + _services.AddScoped(sp => factory(ServiceProviderFactoryAdapter.Wrap(sp))); + break; + case Lifetime.Transient: + _services.AddTransient(sp => factory(ServiceProviderFactoryAdapter.Wrap(sp))); + break; + case Lifetime.Singleton: + _services.AddSingleton(sp => factory(ServiceProviderFactoryAdapter.Wrap(sp))); + break; + default: + throw new NotImplementedException($"Unhandled Lifetime: {lifetime}"); + } + } + public void Register(Type serviceType, object instance) + { + _services.AddSingleton(serviceType, instance); + } + + public IFactory CreateFactory() + { + return ServiceProviderFactoryAdapter.Wrap(_services.BuildServiceProvider()); + } + } + + public class LazyResolve : Lazy + where T : class + { + public LazyResolve(IServiceProvider serviceProvider) : base(serviceProvider.GetRequiredService) + { + + } + } +} diff --git a/src/Umbraco.Infrastructure/Composing/ServiceProviderFactoryAdapter.cs b/src/Umbraco.Infrastructure/Composing/ServiceProviderFactoryAdapter.cs new file mode 100644 index 0000000000..1273e40123 --- /dev/null +++ b/src/Umbraco.Infrastructure/Composing/ServiceProviderFactoryAdapter.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core.Composing; + +namespace Umbraco.Infrastructure.Composing +{ + internal class ServiceProviderFactoryAdapter : IFactory + { + private readonly IServiceProvider _serviceProvider; + + private ServiceProviderFactoryAdapter(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public object Concrete => _serviceProvider; + + public object GetInstance(Type type) + { + return _serviceProvider.GetRequiredService(type); + } + + public object TryGetInstance(Type type) + { + return _serviceProvider.GetService(type); + } + + public IEnumerable GetAllInstances(Type serviceType) + { + return _serviceProvider.GetServices(serviceType); + } + + public IEnumerable GetAllInstances() where TService : class + { + return _serviceProvider.GetServices(); + } + + public IDisposable BeginScope() + { + return _serviceProvider.CreateScope(); + } + + public static IFactory Wrap(IServiceProvider serviceProvider) + { + return new ServiceProviderFactoryAdapter(serviceProvider); + } + } +} diff --git a/src/Umbraco.Infrastructure/Composing/UmbracoServiceProviderFactory.cs b/src/Umbraco.Infrastructure/Composing/UmbracoServiceProviderFactory.cs deleted file mode 100644 index 70737ab569..0000000000 --- a/src/Umbraco.Infrastructure/Composing/UmbracoServiceProviderFactory.cs +++ /dev/null @@ -1,105 +0,0 @@ -using LightInject; -using LightInject.Microsoft.DependencyInjection; -using Microsoft.Extensions.DependencyInjection; -using System; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Umbraco.Composing; -using Umbraco.Core.Composing.LightInject; -using Umbraco.Core.Configuration; -using Umbraco.Core.Configuration.Models; -using Umbraco.Core.IO; - -namespace Umbraco.Core.Composing -{ - /// - /// Used to create Umbraco's container and cross-wire it up before the applicaton starts - /// - public class UmbracoServiceProviderFactory : IServiceProviderFactory - { - public UmbracoServiceProviderFactory(ServiceContainer container, bool initializeCurrent) - { - _container = new LightInjectContainer(container); - _initializeCurrent = initializeCurrent; - } - - /// - /// Creates an ASP.NET Core compatible service container - /// - /// - public static ServiceContainer CreateServiceContainer() => new ServiceContainer( - ContainerOptions.Default.Clone() - .WithMicrosoftSettings() - //.WithAspNetCoreSettings() //TODO WithAspNetCoreSettings changes behavior that we need to discuss - ); - - /// - /// Default ctor for use in Host Builder configuration - /// - public UmbracoServiceProviderFactory() - { - var container = CreateServiceContainer(); - UmbracoContainer = _container = new LightInjectContainer(container); - IsActive = true; - _initializeCurrent = true; - } - - // see here for orig lightinject version https://github.com/seesharper/LightInject.Microsoft.DependencyInjection/blob/412566e3f70625e6b96471db5e1f7cd9e3e1eb18/src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs#L263 - // we don't really need all that, we're manually creating our container with the correct options and that - // is what we'll return in CreateBuilder - - IServiceCollection _services; - readonly LightInjectContainer _container; - private readonly bool _initializeCurrent; - - internal LightInjectContainer GetContainer() => _container; - - /// - /// When the empty ctor is used this returns if this factory is active - /// - public static bool IsActive { get; private set; } - - /// - /// When the empty ctor is used this returns the created IRegister - /// - public static IRegister UmbracoContainer { get; private set; } - - /// - /// Create the container with the required settings for aspnetcore3 - /// - /// - /// - public IServiceContainer CreateBuilder(IServiceCollection services) - { - _services = services; - return _container.Container; - } - - /// - /// This cross-wires the container just before the application calls "Configure" - /// - /// - /// - public IServiceProvider CreateServiceProvider(IServiceContainer containerBuilder) - { - var provider = containerBuilder.CreateServiceProvider(_services); - - if (_initializeCurrent) - { - // after cross wiring, configure "Current" - Current.Initialize( - _container.GetInstance>(), - _container.GetInstance>().Value, - _container.GetInstance>().Value, - _container.GetInstance(), - _container.GetInstance(), - _container.GetInstance(), - _container.GetInstance()); - } - - - return provider; - } - - } -} diff --git a/src/Umbraco.Infrastructure/CompositionExtensions.cs b/src/Umbraco.Infrastructure/CompositionExtensions.cs index d55effcd7a..6ba5c34505 100644 --- a/src/Umbraco.Infrastructure/CompositionExtensions.cs +++ b/src/Umbraco.Infrastructure/CompositionExtensions.cs @@ -282,22 +282,6 @@ namespace Umbraco.Core composition.RegisterUnique(_ => helper); } - /// - /// Sets the underlying media filesystem. - /// - /// A composition. - /// A filesystem factory. - public static void SetMediaFileSystem(this Composition composition, Func filesystemFactory) - => composition.RegisterUniqueFor(filesystemFactory); - - /// - /// Sets the underlying media filesystem. - /// - /// A composition. - /// A filesystem factory. - public static void SetMediaFileSystem(this Composition composition, Func filesystemFactory) - => composition.RegisterUniqueFor(_ => filesystemFactory()); - /// /// Sets the log viewer. /// diff --git a/src/Umbraco.Infrastructure/CompositionExtensions_FileSystems.cs b/src/Umbraco.Infrastructure/CompositionExtensions_FileSystems.cs deleted file mode 100644 index f6c65e1e1f..0000000000 --- a/src/Umbraco.Infrastructure/CompositionExtensions_FileSystems.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Umbraco.Core.Composing; -using Umbraco.Core.IO; - -namespace Umbraco.Core -{ - /// - /// Provides extension methods to the class. - /// - public static partial class CompositionExtensions - { - /// - /// Registers a filesystem. - /// - /// The type of the filesystem. - /// The implementing type. - /// The composition. - /// The register. - public static void RegisterFileSystem(this Composition composition) - where TImplementing : FileSystemWrapper, TFileSystem - where TFileSystem : class - { - composition.RegisterUnique(factory => - { - var fileSystems = factory.GetInstance(); - var supporting = factory.GetInstance(); - return fileSystems.GetFileSystem(supporting.For()); - }); - } - - /// - /// Registers a filesystem. - /// - /// The type of the filesystem. - /// The composition. - /// The register. - public static void RegisterFileSystem(this Composition composition) - where TFileSystem : FileSystemWrapper - { - composition.RegisterUnique(factory => - { - var fileSystems = factory.GetInstance(); - var supporting = factory.GetInstance(); - return fileSystems.GetFileSystem(supporting.For()); - }); - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Infrastructure/HealthCheck/HealthCheckResults.cs b/src/Umbraco.Infrastructure/HealthCheck/HealthCheckResults.cs index 7eebf61b22..1561645be9 100644 --- a/src/Umbraco.Infrastructure/HealthCheck/HealthCheckResults.cs +++ b/src/Umbraco.Infrastructure/HealthCheck/HealthCheckResults.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; using System.Linq; using System.Text; using HeyRed.MarkdownSharp; -using Umbraco.Composing; -using Umbraco.Core.Configuration.HealthChecks; using Microsoft.Extensions.Logging; +using Umbraco.Composing; +using Umbraco.Core.HealthCheck; -namespace Umbraco.Web.HealthCheck +namespace Umbraco.Infrastructure.HealthCheck { public class HealthCheckResults { @@ -16,7 +16,7 @@ namespace Umbraco.Web.HealthCheck private ILogger Logger => Current.Logger; // TODO: inject - public HealthCheckResults(IEnumerable checks) + public HealthCheckResults(IEnumerable checks) { _results = checks.ToDictionary( t => t.Name, diff --git a/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs b/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs index 49981b0b9a..37a3b5b072 100644 --- a/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs +++ b/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs @@ -1,13 +1,13 @@ using System; -using System.Net.Mail; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Options; using Umbraco.Core; -using Umbraco.Core.Configuration; -using Umbraco.Core.Configuration.HealthChecks; using Umbraco.Core.Configuration.Models; +using Umbraco.Core.HealthCheck; +using Umbraco.Core.Models; using Umbraco.Core.Services; +using Umbraco.Infrastructure.HealthCheck; namespace Umbraco.Web.HealthCheck.NotificationMethods { @@ -71,23 +71,19 @@ namespace Umbraco.Web.HealthCheck.NotificationMethods var subject = _textService.Localize("healthcheck/scheduledHealthCheckEmailSubject", new[] { host.ToString() }); var mailSender = new EmailSender(Options.Create(_globalSettings)); - using (var mailMessage = CreateMailMessage(subject, message)) - { - await mailSender.SendAsync(mailMessage); - } + var mailMessage = CreateMailMessage(subject, message); + await mailSender.SendAsync(mailMessage); } - private MailMessage CreateMailMessage(string subject, string message) + private EmailMessage CreateMailMessage(string subject, string message) { var to = _contentSettings.Notifications.Email; if (string.IsNullOrWhiteSpace(subject)) subject = "Umbraco Health Check Status"; - return new MailMessage(to, RecipientEmail, subject, message) - { - IsBodyHtml = message.IsNullOrWhiteSpace() == false && message.Contains("<") && message.Contains(" sqlContext, ConcurrentDictionary> maps) + public AccessMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/AuditEntryMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/AuditEntryMapper.cs index 0592a559bb..f70f3d1bc1 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/AuditEntryMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/AuditEntryMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -12,7 +13,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(AuditEntry))] public sealed class AuditEntryMapper : BaseMapper { - public AuditEntryMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public AuditEntryMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/AuditItemMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/AuditItemMapper.cs index 48e7afdc7e..c31c9a421d 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/AuditItemMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/AuditItemMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -9,7 +10,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IAuditItem))] public sealed class AuditItemMapper : BaseMapper { - public AuditItemMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public AuditItemMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/BaseMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/BaseMapper.cs index a569fa4912..3085ebe624 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/BaseMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/BaseMapper.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using NPoco; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Composing; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -15,12 +16,12 @@ namespace Umbraco.Core.Persistence.Mappers private readonly Lazy _sqlContext; private readonly object _definedLock = new object(); - private readonly ConcurrentDictionary> _maps; + private readonly MapperConfigurationStore _maps; private ISqlSyntaxProvider _sqlSyntax; private bool _defined; - protected BaseMapper(Lazy sqlContext, ConcurrentDictionary> maps) + protected BaseMapper(Lazy sqlContext, MapperConfigurationStore maps) { _sqlContext = sqlContext; _maps = maps; diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/ConsentMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/ConsentMapper.cs index c7eca9909c..b02a9356af 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/ConsentMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/ConsentMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -12,7 +13,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(Consent))] public sealed class ConsentMapper : BaseMapper { - public ConsentMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public ConsentMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/ContentMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/ContentMapper.cs index f707f27e17..d629a1845b 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/ContentMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/ContentMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IContent))] public sealed class ContentMapper : BaseMapper { - public ContentMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public ContentMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/ContentTypeMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/ContentTypeMapper.cs index b14fc546c8..b74aaed560 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/ContentTypeMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/ContentTypeMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IContentType))] public sealed class ContentTypeMapper : BaseMapper { - public ContentTypeMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public ContentTypeMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/DataTypeMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/DataTypeMapper.cs index 5954cb5729..aaa390de5a 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/DataTypeMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/DataTypeMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IDataType))] public sealed class DataTypeMapper : BaseMapper { - public DataTypeMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public DataTypeMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/DictionaryMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/DictionaryMapper.cs index f6a0947bd1..fb69640d90 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/DictionaryMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/DictionaryMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IDictionaryItem))] public sealed class DictionaryMapper : BaseMapper { - public DictionaryMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public DictionaryMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/DictionaryTranslationMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/DictionaryTranslationMapper.cs index 672c8a4b0a..d735014266 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/DictionaryTranslationMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/DictionaryTranslationMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IDictionaryTranslation))] public sealed class DictionaryTranslationMapper : BaseMapper { - public DictionaryTranslationMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public DictionaryTranslationMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/DomainMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/DomainMapper.cs index 9106b76f54..7261b83a26 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/DomainMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/DomainMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -9,7 +10,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(UmbracoDomain))] public sealed class DomainMapper : BaseMapper { - public DomainMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public DomainMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/ExternalLoginMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/ExternalLoginMapper.cs index 223689ec51..208de76339 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/ExternalLoginMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/ExternalLoginMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models.Identity; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -9,7 +10,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IdentityUserLogin))] public sealed class ExternalLoginMapper : BaseMapper { - public ExternalLoginMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public ExternalLoginMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/LanguageMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/LanguageMapper.cs index 8941626b79..38126b0328 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/LanguageMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/LanguageMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(Language))] public sealed class LanguageMapper : BaseMapper { - public LanguageMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public LanguageMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/MacroMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/MacroMapper.cs index f6f7de8347..63980e8622 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/MacroMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/MacroMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -9,7 +10,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IMacro))] internal sealed class MacroMapper : BaseMapper { - public MacroMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public MacroMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs index 951b0cdf93..66f0c90bfa 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs @@ -1,14 +1,12 @@ using System; using System.Collections.Concurrent; using Umbraco.Core.Composing; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { public class MapperCollectionBuilder : SetCollectionBuilderBase { - private readonly ConcurrentDictionary> _maps - = new ConcurrentDictionary>(); - protected override MapperCollectionBuilder This => this; public override void RegisterWith(IRegister register) @@ -21,14 +19,10 @@ namespace Umbraco.Core.Persistence.Mappers // we want to register extra // - service IMapperCollection, returns MappersCollectionBuilder's collection + register.Register(Lifetime.Singleton); register.Register(factory => factory.GetInstance()); } - protected override BaseMapper CreateItem(IFactory factory, Type itemType) - { - return (BaseMapper) factory.CreateInstance(itemType, _maps); - } - public MapperCollectionBuilder AddCoreMappers() { Add(); diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/MapperConfigurationStore.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/MapperConfigurationStore.cs new file mode 100644 index 0000000000..d7fec08be8 --- /dev/null +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/MapperConfigurationStore.cs @@ -0,0 +1,8 @@ +using System; +using System.Collections.Concurrent; + +namespace Umbraco.Infrastructure.Persistence.Mappers +{ + public class MapperConfigurationStore : ConcurrentDictionary> + { } +} diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/MediaMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/MediaMapper.cs index e2504594cd..42568f2871 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/MediaMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/MediaMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(Umbraco.Core.Models.Media))] public sealed class MediaMapper : BaseMapper { - public MediaMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public MediaMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/MediaTypeMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/MediaTypeMapper.cs index 526a2da239..e54ca9f35e 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/MediaTypeMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/MediaTypeMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(MediaType))] public sealed class MediaTypeMapper : BaseMapper { - public MediaTypeMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public MediaTypeMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/MemberGroupMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/MemberGroupMapper.cs index f462c449b5..5d2a7b22a3 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/MemberGroupMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/MemberGroupMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -9,7 +10,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof (MemberGroup))] public sealed class MemberGroupMapper : BaseMapper { - public MemberGroupMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public MemberGroupMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/MemberMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/MemberMapper.cs index 51c453aadc..30e7502984 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/MemberMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/MemberMapper.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -14,7 +15,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(Member))] public sealed class MemberMapper : BaseMapper { - public MemberMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public MemberMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/MemberTypeMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/MemberTypeMapper.cs index 7a6d54c499..3e675dc665 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/MemberTypeMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/MemberTypeMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof (IMemberType))] public sealed class MemberTypeMapper : BaseMapper { - public MemberTypeMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public MemberTypeMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyGroupMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyGroupMapper.cs index 19b5859bcd..4b85b8167e 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyGroupMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyGroupMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -12,7 +13,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(PropertyGroup))] public sealed class PropertyGroupMapper : BaseMapper { - public PropertyGroupMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public PropertyGroupMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyMapper.cs index 354f4a2622..436a5bf3c4 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyMapper.cs @@ -2,13 +2,14 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { [MapperFor(typeof(Property))] public sealed class PropertyMapper : BaseMapper { - public PropertyMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public PropertyMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyTypeMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyTypeMapper.cs index 37bb20285c..8aa95fd13a 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyTypeMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/PropertyTypeMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -12,7 +13,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(PropertyType))] public sealed class PropertyTypeMapper : BaseMapper { - public PropertyTypeMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public PropertyTypeMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/RelationMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/RelationMapper.cs index c7af941d27..22ac0a5583 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/RelationMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/RelationMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(Relation))] public sealed class RelationMapper : BaseMapper { - public RelationMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public RelationMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/RelationTypeMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/RelationTypeMapper.cs index 366a804aa6..15b23f27e5 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/RelationTypeMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/RelationTypeMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IRelationType))] public sealed class RelationTypeMapper : BaseMapper { - public RelationTypeMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public RelationTypeMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/ServerRegistrationMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/ServerRegistrationMapper.cs index 9f3d557e9c..81f495740d 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/ServerRegistrationMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/ServerRegistrationMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -9,7 +10,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IServerRegistration))] internal sealed class ServerRegistrationMapper : BaseMapper { - public ServerRegistrationMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public ServerRegistrationMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/SimpleContentTypeMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/SimpleContentTypeMapper.cs index 68df1550e5..75dd18c228 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/SimpleContentTypeMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/SimpleContentTypeMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -16,7 +17,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(SimpleContentType))] public sealed class SimpleContentTypeMapper : BaseMapper { - public SimpleContentTypeMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public SimpleContentTypeMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/TagMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/TagMapper.cs index 88849e0444..306f69e6f1 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/TagMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/TagMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(ITag))] public sealed class TagMapper : BaseMapper { - public TagMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public TagMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/TemplateMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/TemplateMapper.cs index b9defdee6a..c2e30e485f 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/TemplateMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/TemplateMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(ITemplate))] public sealed class TemplateMapper : BaseMapper { - public TemplateMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public TemplateMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/UmbracoEntityMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/UmbracoEntityMapper.cs index 16e2e8bcd5..776443cbd9 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/UmbracoEntityMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/UmbracoEntityMapper.cs @@ -2,13 +2,14 @@ using System.Collections.Concurrent; using Umbraco.Core.Models.Entities; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { [MapperFor(typeof (IUmbracoEntity))] public sealed class UmbracoEntityMapper : BaseMapper { - public UmbracoEntityMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public UmbracoEntityMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/UserGroupMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/UserGroupMapper.cs index 75d34e4081..addafc5f11 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/UserGroupMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/UserGroupMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -13,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(UserGroup))] public sealed class UserGroupMapper : BaseMapper { - public UserGroupMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public UserGroupMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/UserMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/UserMapper.cs index 4f92b5c224..8af6479362 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/UserMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/UserMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Core.Persistence.Mappers { @@ -9,7 +10,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(User))] public sealed class UserMapper : BaseMapper { - public UserMapper(Lazy sqlContext, ConcurrentDictionary> maps) + public UserMapper(Lazy sqlContext, MapperConfigurationStore maps) : base(sqlContext, maps) { } diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/SimilarNodeName.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/SimilarNodeName.cs index 99e824757d..b613ea84aa 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/SimilarNodeName.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/SimilarNodeName.cs @@ -1,118 +1,225 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; +using static Umbraco.Core.Persistence.Repositories.Implement.SimilarNodeName; namespace Umbraco.Core.Persistence.Repositories.Implement { internal class SimilarNodeName { - private int _numPos = -2; - public int Id { get; set; } public string Name { get; set; } - // cached - reused - public int NumPos - { - get - { - if (_numPos != -2) return _numPos; - - var name = Name; - - // cater nodes with no name. - if (string.IsNullOrWhiteSpace(name)) - return _numPos; - - if (name[name.Length - 1] != ')') - return _numPos = -1; - - var pos = name.LastIndexOf('('); - if (pos < 2 || pos == name.Length - 2) // < 2 and not < 0, because we want at least "x (" - return _numPos = -1; - - return _numPos = pos; - } - } - - // not cached - used only once - public int NumVal - { - get - { - if (NumPos < 0) - throw new InvalidOperationException(); - int num; - if (int.TryParse(Name.Substring(NumPos + 1, Name.Length - 2 - NumPos), out num)) - return num; - return 0; - } - } - - // compare without allocating, nor parsing integers - internal class Comparer : IComparer - { - public int Compare(SimilarNodeName x, SimilarNodeName y) - { - if (x == null) throw new ArgumentNullException("x"); - if (y == null) throw new ArgumentNullException("y"); - - var xpos = x.NumPos; - var ypos = y.NumPos; - - var xname = x.Name; - var yname = y.Name; - - if (xpos < 0 || ypos < 0 || xpos != ypos) - return string.Compare(xname, yname, StringComparison.Ordinal); - - // compare the part before (number) - var n = string.Compare(xname, 0, yname, 0, xpos, StringComparison.Ordinal); - if (n != 0) - return n; - - // compare (number) lengths - var diff = xname.Length - yname.Length; - if (diff != 0) return diff < 0 ? -1 : +1; - - // actually compare (number) - var i = xpos; - while (i < xname.Length - 1) - { - if (xname[i] != yname[i]) - return xname[i] < yname[i] ? -1 : +1; - i++; - } - return 0; - } - } - - // gets a unique name public static string GetUniqueName(IEnumerable names, int nodeId, string nodeName) { - var uniqueNumber = 1; - var uniqueing = false; - foreach (var name in names.OrderBy(x => x, new Comparer())) - { - // ignore self - if (nodeId != 0 && name.Id == nodeId) continue; + var items = names + .Where(x => x.Id != nodeId) // ignore same node + .Select(x => x.Name); - if (uniqueing) + var uniqueName = GetUniqueName(items, nodeName); + + return uniqueName; + } + + public static string GetUniqueName(IEnumerable names, string name) + { + var model = new StructuredName(name); + var items = names + .Where(x => x.InvariantStartsWith(model.Text)) // ignore non-matching names + .Select(x => new StructuredName(x)); + + // name is empty, and there are no other names with suffixes, so just return " (1)" + if (model.IsEmptyName() && !items.Any()) + { + model.Suffix = StructuredName.INITIAL_SUFFIX; + + return model.FullName; + } + + // name is empty, and there are other names with suffixes + if (model.IsEmptyName() && items.SuffixedNameExists()) + { + var emptyNameSuffix = GetSuffixNumber(items); + + if (emptyNameSuffix > 0) { - if (name.NumPos > 0 && name.Name.InvariantStartsWith(nodeName) && name.NumVal == uniqueNumber) - uniqueNumber++; - else - break; - } - else if (name.Name.InvariantEquals(nodeName)) - { - uniqueing = true; + model.Suffix = (uint?)emptyNameSuffix; + + return model.FullName; } } - return uniqueing || string.IsNullOrWhiteSpace(nodeName) - ? string.Concat(nodeName, " (", uniqueNumber.ToString(), ")") - : nodeName; + // no suffix - name without suffix does NOT exist, AND name with suffix does NOT exist + if (!model.Suffix.HasValue && !items.SimpleNameExists(model.Text) && !items.SuffixedNameExists()) + { + model.Suffix = StructuredName.NO_SUFFIX; + + return model.FullName; + } + + // no suffix - name without suffix exists, however name with suffix does NOT exist + if (!model.Suffix.HasValue && items.SimpleNameExists(model.Text) && !items.SuffixedNameExists()) + { + var firstSuffix = GetFirstSuffix(items); + model.Suffix = (uint?)firstSuffix; + + return model.FullName; + } + + // no suffix - name without suffix exists, AND name with suffix does exist + if (!model.Suffix.HasValue && items.SimpleNameExists(model.Text) && items.SuffixedNameExists()) + { + var nextSuffix = GetSuffixNumber(items); + model.Suffix = (uint?)nextSuffix; + + return model.FullName; + } + + // no suffix - name without suffix does NOT exist, however name with suffix exists + if (!model.Suffix.HasValue && !items.SimpleNameExists(model.Text) && items.SuffixedNameExists()) + { + var nextSuffix = GetSuffixNumber(items); + model.Suffix = (uint?)nextSuffix; + + return model.FullName; + } + + // has suffix - name without suffix exists + if (model.Suffix.HasValue && items.SimpleNameExists(model.Text)) + { + var nextSuffix = GetSuffixNumber(items); + model.Suffix = (uint?)nextSuffix; + + return model.FullName; + } + + // has suffix - name without suffix does NOT exist + // a case where the user added the suffix, so add a secondary suffix + if (model.Suffix.HasValue && !items.SimpleNameExists(model.Text)) + { + model.Text = model.FullName; + model.Suffix = StructuredName.NO_SUFFIX; + + // filter items based on full name with suffix + items = items.Where(x => x.Text.InvariantStartsWith(model.FullName)); + var secondarySuffix = GetFirstSuffix(items); + model.Suffix = (uint?)secondarySuffix; + + return model.FullName; + } + + // has suffix - name without suffix also exists, therefore we simply increment + if (model.Suffix.HasValue && items.SimpleNameExists(model.Text)) + { + var nextSuffix = GetSuffixNumber(items); + model.Suffix = (uint?)nextSuffix; + + return model.FullName; + } + + return name; + } + + private static int GetFirstSuffix(IEnumerable items) + { + const int suffixStart = 1; + + if (!items.Any(x => x.Suffix == suffixStart)) + { + // none of the suffixes are the same as suffixStart, so we can use suffixStart! + return suffixStart; + } + + return GetSuffixNumber(items); + } + + private static int GetSuffixNumber(IEnumerable items) + { + int current = 1; + foreach (var item in items.OrderBy(x => x.Suffix)) + { + if (item.Suffix == current) + { + current++; + } + else if (item.Suffix > current) + { + // do nothing - we found our number! + // eg. when suffixes are 1 & 3, then this method is required to generate 2 + break; + } + } + + return current; + } + + internal class StructuredName + { + const string SPACE_CHARACTER = " "; + const string SUFFIXED_PATTERN = @"(.*) \(([1-9]\d*)\)$"; + internal const uint INITIAL_SUFFIX = 1; + internal static readonly uint? NO_SUFFIX = default; + + internal string Text { get; set; } + internal uint ? Suffix { get; set; } + public string FullName + { + get + { + string text = (Text == SPACE_CHARACTER) ? Text.Trim() : Text; + + return Suffix > 0 ? $"{text} ({Suffix})" : text; + } + } + + internal StructuredName(string name) + { + if (string.IsNullOrWhiteSpace(name)) + { + Text = SPACE_CHARACTER; + + return; + } + + var rg = new Regex(SUFFIXED_PATTERN); + var matches = rg.Matches(name); + if (matches.Count > 0) + { + var match = matches[0]; + Text = match.Groups[1].Value; + int number = int.TryParse(match.Groups[2].Value, out number) ? number : 0; + Suffix = (uint?)(number); + + return; + } + else + { + Text = name; + } + } + + internal bool IsEmptyName() + { + return string.IsNullOrWhiteSpace(Text); + } + } + } + + internal static class ListExtensions + { + internal static bool Contains(this IEnumerable items, StructuredName model) + { + return items.Any(x => x.FullName.InvariantEquals(model.FullName)); + } + + internal static bool SimpleNameExists(this IEnumerable items, string name) + { + return items.Any(x => x.FullName.InvariantEquals(name)); + } + + internal static bool SuffixedNameExists(this IEnumerable items) + { + return items.Any(x => x.Suffix.HasValue); } } } diff --git a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs index 601a12ac1c..f9ec706ab7 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs @@ -58,7 +58,9 @@ using Umbraco.Web.Trees; using IntegerValidator = Umbraco.Core.PropertyEditors.Validators.IntegerValidator; using TextStringValueConverter = Umbraco.Core.PropertyEditors.ValueConverters.TextStringValueConverter; using Microsoft.Extensions.Logging; - +using Umbraco.Core.Configuration.HealthChecks; +using Umbraco.Core.HealthCheck; +using Umbraco.Core.HealthCheck.Checks; namespace Umbraco.Core.Runtime { @@ -205,7 +207,7 @@ namespace Umbraco.Core.Runtime // Config manipulator composition.RegisterUnique(); - + // register the umbraco context factory // composition.RegisterUnique(); composition.RegisterUnique(); @@ -298,7 +300,7 @@ namespace Umbraco.Core.Runtime // register *all* checks, except those marked [HideFromTypeFinder] of course composition.HealthChecks() - .Add(() => composition.TypeLoader.GetTypes()); + .Add(() => composition.TypeLoader.GetTypes()); composition.WithCollectionBuilder() diff --git a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs index 4f921aa0c7..56cd2ecbc3 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs @@ -15,6 +15,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Mappers; +using Umbraco.Infrastructure.Composing; namespace Umbraco.Core.Runtime { @@ -258,12 +259,6 @@ namespace Umbraco.Core.Runtime // create & initialize the components _components = _factory.GetInstance(); _components.Initialize(); - - // now (and only now) is the time to switch over to perWebRequest scopes. - // up until that point we may not have a request, and scoped services would - // fail to resolve - but we run Initialize within a factory scope - and then, - // here, we switch the factory to bind scopes to requests - _factory.EnablePerWebRequestScope(); } protected virtual void ConfigureUnhandledException() @@ -361,6 +356,10 @@ namespace Umbraco.Core.Runtime _components?.Terminate(); } + public void ReplaceFactory(IServiceProvider serviceProvider) + { + _factory = ServiceProviderFactoryAdapter.Wrap(serviceProvider); + } #region Getters diff --git a/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs b/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs index 6198e7845d..33eff2c949 100644 --- a/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs +++ b/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs @@ -3,11 +3,13 @@ using System.Threading; using System.Threading.Tasks; using Umbraco.Core; using Umbraco.Core.Configuration.Models; +using Umbraco.Core.HealthCheck; using Umbraco.Core.Logging; using Umbraco.Core.Scoping; using Umbraco.Core.Sync; using Umbraco.Web.HealthCheck; using Microsoft.Extensions.Logging; +using Umbraco.Infrastructure.HealthCheck; namespace Umbraco.Web.Scheduling { diff --git a/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs b/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs index c96071ff04..6e4b4bb629 100644 --- a/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs +++ b/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs @@ -7,8 +7,8 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Umbraco.Core; using Umbraco.Core.Composing; -using Umbraco.Core.Configuration.HealthChecks; using Umbraco.Core.Configuration.Models; +using Umbraco.Core.HealthCheck; using Umbraco.Core.Hosting; using Umbraco.Core.Logging; using Umbraco.Core.Scoping; diff --git a/src/Umbraco.Infrastructure/Services/Implement/NotificationService.cs b/src/Umbraco.Infrastructure/Services/Implement/NotificationService.cs index 7964cd273e..83d1176402 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/NotificationService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/NotificationService.cs @@ -3,7 +3,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Net.Mail; using System.Text; using System.Threading; using Microsoft.Extensions.Options; @@ -179,7 +178,7 @@ namespace Umbraco.Core.Services.Implement /// public IEnumerable FilterUserNotificationsByPath(IEnumerable userNotifications, string path) { - var pathParts = path.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); + var pathParts = path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return userNotifications.Where(r => pathParts.InvariantContains(r.EntityId.ToString(CultureInfo.InvariantCulture))).ToList(); } @@ -406,22 +405,19 @@ namespace Umbraco.Core.Services.Implement summary.ToString()); var fromMail = _contentSettings.Notifications.Email ?? _globalSettings.Smtp.From; - // create the mail message - var mail = new MailMessage(fromMail, fromMail); - // populate the message + var subject = createSubject((mailingUser, subjectVars)); + var body = ""; + var isBodyHtml = false; - - mail.Subject = createSubject((mailingUser, subjectVars)); if (_contentSettings.Notifications.DisableHtmlEmail) { - mail.IsBodyHtml = false; - mail.Body = createBody((user: mailingUser, body: bodyVars, false)); + body = createBody((user: mailingUser, body: bodyVars, false)); } else { - mail.IsBodyHtml = true; - mail.Body = + isBodyHtml = true; + body = string.Concat(@" @@ -430,14 +426,17 @@ namespace Umbraco.Core.Services.Implement // nh, issue 30724. Due to hardcoded http strings in resource files, we need to check for https replacements here // adding the server name to make sure we don't replace external links - if (_globalSettings.UseHttps && string.IsNullOrEmpty(mail.Body) == false) + if (_globalSettings.UseHttps && string.IsNullOrEmpty(body) == false) { - string serverName = siteUri.Host; - mail.Body = mail.Body.Replace( - string.Format("http://{0}", serverName), - string.Format("https://{0}", serverName)); + var serverName = siteUri.Host; + body = body.Replace( + $"http://{serverName}", + $"https://{serverName}"); } + // create the mail message + var mail = new EmailMessage(fromMail, mailingUser.Email, subject, body, isBodyHtml); + return new NotificationRequest(mail, actionName, mailingUser.Name, mailingUser.Email); } @@ -488,7 +487,7 @@ namespace Umbraco.Core.Services.Implement private class NotificationRequest { - public NotificationRequest(MailMessage mail, string action, string userName, string email) + public NotificationRequest(EmailMessage mail, string action, string userName, string email) { Mail = mail; Action = action; @@ -496,13 +495,13 @@ namespace Umbraco.Core.Services.Implement Email = email; } - public MailMessage Mail { get; private set; } + public EmailMessage Mail { get; } - public string Action { get; private set; } + public string Action { get; } - public string UserName { get; private set; } + public string UserName { get; } - public string Email { get; private set; } + public string Email { get; } } private void Process(BlockingCollection notificationRequests) @@ -524,10 +523,6 @@ namespace Umbraco.Core.Services.Implement { _logger.LogError(ex, "An error occurred sending notification"); } - finally - { - request.Mail.Dispose(); - } } lock (Locker) { diff --git a/src/Umbraco.Infrastructure/Services/Implement/PropertyValidationService.cs b/src/Umbraco.Infrastructure/Services/Implement/PropertyValidationService.cs index a17cdb034d..c08c1322d3 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/PropertyValidationService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/PropertyValidationService.cs @@ -21,7 +21,6 @@ namespace Umbraco.Core.Services _textService = textService; } - public IEnumerable ValidatePropertyValue( IPropertyType propertyType, object postedValue) diff --git a/src/Umbraco.Infrastructure/Users/EmailSender.cs b/src/Umbraco.Infrastructure/Users/EmailSender.cs index c45a9af0d3..a58426d82f 100644 --- a/src/Umbraco.Infrastructure/Users/EmailSender.cs +++ b/src/Umbraco.Infrastructure/Users/EmailSender.cs @@ -1,13 +1,12 @@ using System; -using System.Linq; using System.Net.Mail; using System.Threading.Tasks; using Microsoft.Extensions.Options; using MimeKit; using MimeKit.Text; -using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Events; +using Umbraco.Core.Models; using SmtpClient = MailKit.Net.Smtp.SmtpClient; namespace Umbraco.Core @@ -40,7 +39,7 @@ namespace Umbraco.Core /// Sends the message non-async /// /// - public void Send(MailMessage message) + public void Send(EmailMessage message) { if (_smtpConfigured.Value == false && _enableEvents) { @@ -70,7 +69,7 @@ namespace Umbraco.Core /// /// /// - public async Task SendAsync(MailMessage message) + public async Task SendAsync(EmailMessage message) { if (_smtpConfigured.Value == false && _enableEvents) { @@ -130,9 +129,9 @@ namespace Umbraco.Core if (handler != null) handler(null, e); } - private MimeMessage ConstructEmailMessage(MailMessage mailMessage) + private MimeMessage ConstructEmailMessage(EmailMessage mailMessage) { - var fromEmail = mailMessage.From?.Address; + var fromEmail = mailMessage.From; if(string.IsNullOrEmpty(fromEmail)) fromEmail = _globalSettings.Smtp.From; @@ -142,7 +141,7 @@ namespace Umbraco.Core From = { new MailboxAddress(fromEmail)}, Body = new TextPart(mailMessage.IsBodyHtml ? TextFormat.Html : TextFormat.Plain) { Text = mailMessage.Body } }; - messageToSend.To.AddRange(mailMessage.To.Select(x=>new MailboxAddress(x.Address))); + messageToSend.To.Add(new MailboxAddress(mailMessage.To)); return messageToSend; } diff --git a/src/Umbraco.Tests.Benchmarks/ModelToSqlExpressionHelperBenchmarks.cs b/src/Umbraco.Tests.Benchmarks/ModelToSqlExpressionHelperBenchmarks.cs index 6eb955ea8f..2b247ce2fc 100644 --- a/src/Umbraco.Tests.Benchmarks/ModelToSqlExpressionHelperBenchmarks.cs +++ b/src/Umbraco.Tests.Benchmarks/ModelToSqlExpressionHelperBenchmarks.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Infrastructure.Persistence.Mappers; using Umbraco.Persistance.SqlCe; namespace Umbraco.Tests.Benchmarks @@ -24,8 +25,8 @@ namespace Umbraco.Tests.Benchmarks return new Lazy(() => sqlContext); } - protected ConcurrentDictionary> CreateMaps() - => new ConcurrentDictionary>(); + protected MapperConfigurationStore CreateMaps() + => new MapperConfigurationStore(); public ModelToSqlExpressionHelperBenchmarks() { diff --git a/src/Umbraco.Tests.Benchmarks/SqlTemplatesBenchmark.cs b/src/Umbraco.Tests.Benchmarks/SqlTemplatesBenchmark.cs index 22912af9ff..355421b1d5 100644 --- a/src/Umbraco.Tests.Benchmarks/SqlTemplatesBenchmark.cs +++ b/src/Umbraco.Tests.Benchmarks/SqlTemplatesBenchmark.cs @@ -53,9 +53,9 @@ namespace Umbraco.Tests.Benchmarks for (var i = 0; i < 100; i++) { var sql = Sql.BuilderFor(SqlContext) - .Select() - .From() - .Where(x => x.Name == "yada"); + .Select() + .From() + .Where(x => x.Name == "yada"); var sqlString = sql.SQL; // force-build the SQL } @@ -69,9 +69,9 @@ namespace Umbraco.Tests.Benchmarks for (var i = 0; i < 100; i++) { var template = SqlTemplates.Get("test", s => s - .Select() - .From() - .Where(x => x.Name == SqlTemplate.Arg("name"))); + .Select() + .From() + .Where(x => x.Name == SqlTemplate.Arg("name"))); var sql = template.Sql(new { name = "yada" }); @@ -79,5 +79,17 @@ namespace Umbraco.Tests.Benchmarks } } + [TableName("zbThing1")] + [PrimaryKey("id", AutoIncrement = false)] + [ExplicitColumns] + public class Thing1Dto + { + [Column("id")] + public int Id { get; set; } + + [Column("name")] + public string Name { get; set; } + } + } } diff --git a/src/Umbraco.Tests.Common/Builders/ContentBuilder.cs b/src/Umbraco.Tests.Common/Builders/ContentBuilder.cs index 9f30005c55..283b2b6c04 100644 --- a/src/Umbraco.Tests.Common/Builders/ContentBuilder.cs +++ b/src/Umbraco.Tests.Common/Builders/ContentBuilder.cs @@ -30,6 +30,7 @@ namespace Umbraco.Tests.Common.Builders private GenericDictionaryBuilder _propertyDataBuilder; private int? _id; + private int? _versionId; private Guid? _key; private DateTime? _createDate; private DateTime? _updateDate; @@ -48,12 +49,10 @@ namespace Umbraco.Tests.Common.Builders private string _propertyValuesCulture; private string _propertyValuesSegment; - public ContentTypeBuilder AddContentType() + public ContentBuilder WithVersionId(int versionId) { - _contentType = null; - var builder = new ContentTypeBuilder(this); - _contentTypeBuilder = builder; - return builder; + _versionId = versionId; + return this; } public ContentBuilder WithParent(IContent parent) @@ -87,6 +86,14 @@ namespace Umbraco.Tests.Common.Builders return this; } + public ContentTypeBuilder AddContentType() + { + _contentType = null; + var builder = new ContentTypeBuilder(this); + _contentTypeBuilder = builder; + return builder; + } + public GenericDictionaryBuilder AddPropertyData() { var builder = new GenericDictionaryBuilder(this); @@ -97,6 +104,7 @@ namespace Umbraco.Tests.Common.Builders public override Content Build() { var id = _id ?? 0; + var versionId = _versionId ?? 0; var key = _key ?? Guid.NewGuid(); var parentId = _parentId ?? -1; var parent = _parent ?? null; @@ -131,6 +139,7 @@ namespace Umbraco.Tests.Common.Builders } content.Id = id; + content.VersionId = versionId; content.Key = key; content.CreateDate = createDate; content.UpdateDate = updateDate; diff --git a/src/Umbraco.Tests.Common/Builders/ContentTypeBuilder.cs b/src/Umbraco.Tests.Common/Builders/ContentTypeBuilder.cs index eb4192364f..fca148f542 100644 --- a/src/Umbraco.Tests.Common/Builders/ContentTypeBuilder.cs +++ b/src/Umbraco.Tests.Common/Builders/ContentTypeBuilder.cs @@ -20,6 +20,7 @@ namespace Umbraco.Tests.Common.Builders private int? _propertyTypeIdsIncrementingFrom; private int? _defaultTemplateId; private ContentVariation? _contentVariation; + private PropertyTypeCollection _propertyTypeCollection; public ContentTypeBuilder() : base(null) { @@ -41,6 +42,12 @@ namespace Umbraco.Tests.Common.Builders return this; } + public ContentTypeBuilder WithPropertyTypeCollection(PropertyTypeCollection propertyTypeCollection) + { + _propertyTypeCollection = propertyTypeCollection; + return this; + } + public PropertyGroupBuilder AddPropertyGroup() { var builder = new PropertyGroupBuilder(this); @@ -104,9 +111,21 @@ namespace Umbraco.Tests.Common.Builders contentType.Variations = contentVariation; - contentType.NoGroupPropertyTypes = _noGroupPropertyTypeBuilders.Select(x => x.Build()); - BuildPropertyGroups(contentType, _propertyGroupBuilders.Select(x => x.Build())); - BuildPropertyTypeIds(contentType, _propertyTypeIdsIncrementingFrom); + if (_propertyTypeCollection != null) + { + var propertyGroup = new PropertyGroupBuilder() + .WithName("Content") + .WithSortOrder(1) + .WithPropertyTypeCollection(_propertyTypeCollection) + .Build(); + contentType.PropertyGroups.Add(propertyGroup); + } + else + { + contentType.NoGroupPropertyTypes = _noGroupPropertyTypeBuilders.Select(x => x.Build()); + BuildPropertyGroups(contentType, _propertyGroupBuilders.Select(x => x.Build())); + BuildPropertyTypeIds(contentType, _propertyTypeIdsIncrementingFrom); + } contentType.AllowedContentTypes = _allowedContentTypeBuilders.Select(x => x.Build()); @@ -134,7 +153,7 @@ namespace Umbraco.Tests.Common.Builders public static ContentType CreateSimpleContentType2(string alias, string name, IContentType parent = null, bool randomizeAliases = false, string propertyGroupName = "Content") { - var builder = CreateSimpleContentTypeHelper(alias, name, parent, randomizeAliases, propertyGroupName); + var builder = CreateSimpleContentTypeHelper(alias, name, parent, randomizeAliases: randomizeAliases, propertyGroupName: propertyGroupName); builder.AddPropertyType() .WithAlias(RandomAlias("gen", randomizeAliases)) @@ -146,54 +165,70 @@ namespace Umbraco.Tests.Common.Builders .Done(); return (ContentType)builder.Build(); - }public static ContentType CreateSimpleContentType(string alias = null, string name = null, IContentType parent = null, bool randomizeAliases = false, string propertyGroupName = "Content", bool mandatoryProperties = false, int defaultTemplateId = 0) - { - return (ContentType)CreateSimpleContentTypeHelper(alias, name, parent, randomizeAliases, propertyGroupName, mandatoryProperties, defaultTemplateId).Build(); } - public static ContentTypeBuilder CreateSimpleContentTypeHelper(string alias = null, string name = null, IContentType parent = null, bool randomizeAliases = false, string propertyGroupName = "Content", bool mandatoryProperties = false, int defaultTemplateId = 0) + public static ContentType CreateSimpleContentType(string alias = null, string name = null, IContentType parent = null, PropertyTypeCollection propertyTypeCollection = null, bool randomizeAliases = false, string propertyGroupName = "Content", bool mandatoryProperties = false, int defaultTemplateId = 0) { - return new ContentTypeBuilder() + return (ContentType)CreateSimpleContentTypeHelper(alias, name, parent, propertyTypeCollection, randomizeAliases, propertyGroupName, mandatoryProperties, defaultTemplateId).Build(); + } + + public static ContentTypeBuilder CreateSimpleContentTypeHelper(string alias = null, string name = null, IContentType parent = null, PropertyTypeCollection propertyTypeCollection = null, bool randomizeAliases = false, string propertyGroupName = "Content", bool mandatoryProperties = false, int defaultTemplateId = 0) + { + var builder = new ContentTypeBuilder() .WithAlias(alias ?? "simple") .WithName(name ?? "Simple Page") - .WithParentContentType(parent) - .AddPropertyGroup() - .WithName(propertyGroupName) - .WithSortOrder(1) - .WithSupportsPublishing(true) - .AddPropertyType() - .WithAlias(RandomAlias("title", randomizeAliases)) - .WithName("Title") + .WithParentContentType(parent); + + if (propertyTypeCollection != null) + { + builder = builder + .WithPropertyTypeCollection(propertyTypeCollection); + } + else + { + builder = builder + .AddPropertyGroup() + .WithName(propertyGroupName) .WithSortOrder(1) - .WithMandatory(mandatoryProperties) - .Done() - .AddPropertyType() - .WithPropertyEditorAlias(Constants.PropertyEditors.Aliases.TinyMce) - .WithValueStorageType(ValueStorageType.Ntext) - .WithAlias(RandomAlias("bodyText", randomizeAliases)) - .WithName("Body text") - .WithSortOrder(2) - .WithDataTypeId(Constants.DataTypes.RichtextEditor) - .WithMandatory(mandatoryProperties) - .Done() - .AddPropertyType() - .WithAlias(RandomAlias("author", randomizeAliases)) - .WithName("Author") - .WithSortOrder(3) - .WithMandatory(mandatoryProperties) - .Done() + .WithSupportsPublishing(true) + .AddPropertyType() + .WithAlias(RandomAlias("title", randomizeAliases)) + .WithName("Title") + .WithSortOrder(1) + .WithMandatory(mandatoryProperties) + .Done() + .AddPropertyType() + .WithPropertyEditorAlias(Constants.PropertyEditors.Aliases.TinyMce) + .WithValueStorageType(ValueStorageType.Ntext) + .WithAlias(RandomAlias("bodyText", randomizeAliases)) + .WithName("Body text") + .WithSortOrder(2) + .WithDataTypeId(Constants.DataTypes.RichtextEditor) + .WithMandatory(mandatoryProperties) + .Done() + .AddPropertyType() + .WithAlias(RandomAlias("author", randomizeAliases)) + .WithName("Author") + .WithSortOrder(3) + .WithMandatory(mandatoryProperties) + .Done() + .Done(); + } + + builder = builder + .AddAllowedTemplate() + .WithId(defaultTemplateId) + .WithAlias("textPage") + .WithName("Textpage") .Done() - .AddAllowedTemplate() - .WithId(defaultTemplateId) - .WithAlias("textPage") - .WithName("Textpage") - .Done() - .WithDefaultTemplateId(defaultTemplateId); + .WithDefaultTemplateId(defaultTemplateId); + + return builder; } public static ContentType CreateSimpleTagsContentType(string alias, string name, IContentType parent = null, bool randomizeAliases = false, string propertyGroupName = "Content", int defaultTemplateId = 1) { - var contentType = CreateSimpleContentType(alias, name, parent, randomizeAliases, propertyGroupName, defaultTemplateId: defaultTemplateId); + var contentType = CreateSimpleContentType(alias, name, parent, randomizeAliases: randomizeAliases, propertyGroupName: propertyGroupName, defaultTemplateId: defaultTemplateId); var propertyType = new PropertyTypeBuilder() .WithPropertyEditorAlias(Constants.PropertyEditors.Aliases.Tags) @@ -215,7 +250,6 @@ namespace Umbraco.Tests.Common.Builders .WithAlias(alias) .WithName(name) .AddPropertyGroup() - .WithId(1) .WithName("Content") .WithSortOrder(1) .WithSupportsPublishing(true) @@ -234,7 +268,6 @@ namespace Umbraco.Tests.Common.Builders .Done() .Done() .AddPropertyGroup() - .WithId(2) .WithName("Meta") .WithSortOrder(2) .WithSupportsPublishing(true) diff --git a/src/Umbraco.Tests.Common/Builders/PropertyBuilder.cs b/src/Umbraco.Tests.Common/Builders/PropertyBuilder.cs index 6cb7a431f2..a79141b11c 100644 --- a/src/Umbraco.Tests.Common/Builders/PropertyBuilder.cs +++ b/src/Umbraco.Tests.Common/Builders/PropertyBuilder.cs @@ -18,9 +18,18 @@ namespace Umbraco.Tests.Common.Builders private Guid? _key; private DateTime? _createDate; private DateTime? _updateDate; + private IPropertyType _propertyType; + + public PropertyBuilder WithPropertyType(IPropertyType propertyType) + { + _propertyTypeBuilder = null; + _propertyType = propertyType; + return this; + } public PropertyTypeBuilder AddPropertyType() { + _propertyType = null; var builder = new PropertyTypeBuilder(this); _propertyTypeBuilder = builder; return builder; @@ -33,8 +42,15 @@ namespace Umbraco.Tests.Common.Builders var createDate = _createDate ?? DateTime.Now; var updateDate = _updateDate ?? DateTime.Now; + if (_propertyTypeBuilder is null && _propertyType is null) + { + throw new InvalidOperationException("A property cannot be constructed without providing a property type. Use AddPropertyType() or WithPropertyType()."); + } + + var propertyType = _propertyType ?? _propertyTypeBuilder.Build(); + // Needs to be within collection to support publishing. - var propertyTypeCollection = new PropertyTypeCollection(true, new[] { _propertyTypeBuilder.Build() }); + var propertyTypeCollection = new PropertyTypeCollection(true, new[] { propertyType }); return new Property(id, propertyTypeCollection[0]) { diff --git a/src/Umbraco.Tests.Common/Builders/PropertyGroupBuilder.cs b/src/Umbraco.Tests.Common/Builders/PropertyGroupBuilder.cs index f153283764..8fe6e1463d 100644 --- a/src/Umbraco.Tests.Common/Builders/PropertyGroupBuilder.cs +++ b/src/Umbraco.Tests.Common/Builders/PropertyGroupBuilder.cs @@ -37,11 +37,18 @@ namespace Umbraco.Tests.Common.Builders private string _name; private int? _sortOrder; private bool? _supportsPublishing; + private PropertyTypeCollection _propertyTypeCollection; public PropertyGroupBuilder(TParent parentBuilder) : base(parentBuilder) { } + public PropertyGroupBuilder WithPropertyTypeCollection(PropertyTypeCollection propertyTypeCollection) + { + _propertyTypeCollection = propertyTypeCollection; + return this; + } + public PropertyTypeBuilder> AddPropertyType() { var builder = new PropertyTypeBuilder>(this); @@ -51,7 +58,7 @@ namespace Umbraco.Tests.Common.Builders public override PropertyGroup Build() { - var id = _id ?? 1; + var id = _id ?? 0; var key = _key ?? Guid.NewGuid(); var createDate = _createDate ?? DateTime.Now; var updateDate = _updateDate ?? DateTime.Now; @@ -59,13 +66,21 @@ namespace Umbraco.Tests.Common.Builders var sortOrder = _sortOrder ?? 0; var supportsPublishing = _supportsPublishing ?? false; - var properties = new PropertyTypeCollection(supportsPublishing); - foreach (var propertyType in _propertyTypeBuilders.Select(x => x.Build())) + PropertyTypeCollection propertyTypeCollection; + if (_propertyTypeCollection != null) { - properties.Add(propertyType); + propertyTypeCollection = _propertyTypeCollection; + } + else + { + propertyTypeCollection = new PropertyTypeCollection(supportsPublishing); + foreach (var propertyType in _propertyTypeBuilders.Select(x => x.Build())) + { + propertyTypeCollection.Add(propertyType); + } } - return new PropertyGroup(properties) + return new PropertyGroup(propertyTypeCollection) { Id = id, Key = key, diff --git a/src/Umbraco.Tests.Common/TestHelpers/MockedValueEditors.cs b/src/Umbraco.Tests.Common/TestHelpers/MockedValueEditors.cs index 954dedd3b4..78aa0c7bc6 100644 --- a/src/Umbraco.Tests.Common/TestHelpers/MockedValueEditors.cs +++ b/src/Umbraco.Tests.Common/TestHelpers/MockedValueEditors.cs @@ -1,4 +1,4 @@ -using Moq; +using Moq; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Core.Strings; diff --git a/src/Umbraco.Tests.Integration/ContainerTests.cs b/src/Umbraco.Tests.Integration/ContainerTests.cs deleted file mode 100644 index 6b4026057b..0000000000 --- a/src/Umbraco.Tests.Integration/ContainerTests.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System.Threading.Tasks; -using LightInject; -using LightInject.Microsoft.DependencyInjection; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Moq; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Composing; -using Umbraco.Core.Composing.LightInject; -using Umbraco.Core.Configuration; -using Umbraco.Core.Persistence; -using Umbraco.Tests.Common; -using Umbraco.Tests.Integration.Implementations; -using Umbraco.Tests.Integration.Testing; - -namespace Umbraco.Tests.Integration -{ - - [TestFixture] - public class ContainerTests - { - [Explicit("This test just shows that resolving services from the container before the host is done resolves 2 different instances")] - [Test] - public async Task BuildServiceProvider_Before_Host_Is_Configured() - { - // This is a test to show an anti-pattern used in netcore. This should be avoided in all cases if possible. - // There's a thread about this here: https://github.com/dotnet/aspnetcore/issues/14587 - // For some reason we are not being warned about this with our code analysis since we are using it - // in a couple of places but we should really try to see if we can avoid it. - // The test below shows how it could be possible to resolve an instance and then re-register it as a factory - // so that only one singleton instance is every created, but it's hacky and like Fowler says in that article - // it means the container won't be disposed, and maybe other services? not sure. - // In cases where we use it can we use IConfigureOptions? https://andrewlock.net/access-services-inside-options-and-startup-using-configureoptions/ - - var umbracoContainer = UmbracoIntegrationTest.CreateUmbracoContainer(out var serviceProviderFactory); - - IHostApplicationLifetime lifetime1 = null; - - var hostBuilder = new HostBuilder() - .UseUmbraco(serviceProviderFactory) - .ConfigureServices((hostContext, services) => - { - // Resolve a service from the netcore container before the host has finished the ConfigureServices sequence - lifetime1 = services.BuildServiceProvider().GetRequiredService(); - - // Re-add as a callback, ensures its the same instance all the way through (hack) - services.AddSingleton(x => lifetime1); - }); - - var host = await hostBuilder.StartAsync(); - - var lifetime2 = host.Services.GetRequiredService(); - var lifetime3 = umbracoContainer.GetInstance(); - - lifetime1.StopApplication(); - Assert.IsTrue(lifetime1.ApplicationStopping.IsCancellationRequested); - Assert.AreEqual(lifetime1.ApplicationStopping.IsCancellationRequested, lifetime2.ApplicationStopping.IsCancellationRequested); - Assert.AreEqual(lifetime1.ApplicationStopping.IsCancellationRequested, lifetime3.ApplicationStopping.IsCancellationRequested); - - } - - [Test] - public void CrossWire() - { - // MSDI - var services = new ServiceCollection(); - services.AddSingleton(); - var msdiServiceProvider = services.BuildServiceProvider(); - - // LightInject / Umbraco - var container = UmbracoServiceProviderFactory.CreateServiceContainer(); - var serviceProviderFactory = new UmbracoServiceProviderFactory(container, false); - var umbracoContainer = serviceProviderFactory.GetContainer(); - - serviceProviderFactory.CreateBuilder(services); // called during Host Builder, needed to capture services - - // Dependencies needed for creating composition/register essentials - var testHelper = new TestHelper(); - var runtimeState = Mock.Of(); - var umbracoDatabaseFactory = Mock.Of(); - var dbProviderFactoryCreator = Mock.Of(); - var typeLoader = testHelper.GetMockedTypeLoader(); - var loggerFactory = testHelper.ConsoleLoggerFactory; - var logger = testHelper.ConsoleLoggerFactory.CreateLogger("RegisterEssentials"); - - // Register in the container - var composition = new Composition(umbracoContainer, typeLoader, - testHelper.ProfilingLogger, runtimeState, testHelper.IOHelper, testHelper.AppCaches); - composition.RegisterEssentials(logger, loggerFactory, testHelper.Profiler, testHelper.ProfilingLogger, testHelper.MainDom, - testHelper.AppCaches, umbracoDatabaseFactory, typeLoader, runtimeState, testHelper.GetTypeFinder(), - testHelper.IOHelper, testHelper.GetUmbracoVersion(), dbProviderFactoryCreator, - testHelper.GetHostingEnvironment(), testHelper.GetBackOfficeInfo()); - - // Cross wire - this would be called by the Host Builder at the very end of ConfigureServices - var lightInjectServiceProvider = serviceProviderFactory.CreateServiceProvider(umbracoContainer.Container); - - // From MSDI - var foo1 = msdiServiceProvider.GetService(); - var foo2 = lightInjectServiceProvider.GetService(); - var foo3 = umbracoContainer.GetInstance(); - - Assert.IsNotNull(foo1); - Assert.IsNotNull(foo2); - Assert.IsNotNull(foo3); - - // These are not the same because cross wiring means copying the container, not falling back to a container - Assert.AreNotSame(foo1, foo2); - // These are the same because the umbraco container wraps the light inject container - Assert.AreSame(foo2, foo3); - - Assertions.AssertContainer(umbracoContainer.Container); - } - - private class Foo - { - public Foo() - { - } - } - } -} diff --git a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs index 22b3821b3c..7eafdc6271 100644 --- a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs +++ b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Net; using System.Reflection; +using System.Threading; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.FileProviders; @@ -28,6 +29,7 @@ using Umbraco.Core.Runtime; using Umbraco.Net; using Umbraco.Tests.Common; using Umbraco.Web.Common.AspNetCore; +using File = System.IO.File; using IHostingEnvironment = Umbraco.Core.Hosting.IHostingEnvironment; namespace Umbraco.Tests.Integration.Implementations @@ -163,7 +165,7 @@ namespace Umbraco.Tests.Integration.Implementations public void AssertPropertyValuesAreEqual(object actual, object expected, string dateTimeFormat = null, Func sorter = null, string[] ignoreProperties = null) { - const int dateDeltaMilliseconds = 500; // .5s + const int dateDeltaMilliseconds = 1000; // 1s var properties = expected.GetType().GetProperties(); foreach (var property in properties) @@ -173,7 +175,7 @@ namespace Umbraco.Tests.Integration.Implementations if (att != null && att.State == EditorBrowsableState.Never) continue; - // ignore explicitely ignored properties + // ignore explicitly ignored properties if (ignoreProperties != null && ignoreProperties.Contains(property.Name)) continue; @@ -209,7 +211,7 @@ namespace Umbraco.Tests.Integration.Implementations AssertAreEqual(property, expectedListEx[i], actualListEx[i], sorter, dateDeltaMilliseconds); } - private static void AssertAreEqual(PropertyInfo property, object expected, object actual, Func sorter = null, int dateDeltaMilliseconds = 0) + private static void AssertAreEqual(PropertyInfo property, object expected, object actual, Func sorter = null, int dateDeltaMilliseconds = 0) { if (!(expected is string) && expected is IEnumerable) { @@ -238,8 +240,27 @@ namespace Umbraco.Tests.Integration.Implementations Assert.Fail($"{property.DeclaringType.Name}.{property.Name}: Expected {expectedPropertyValues.Length} but got {actualPropertyValues.Length}."); for (var i = 0; i < expectedPropertyValues.Length; i++) { - Assert.AreEqual(expectedPropertyValues[i].EditedValue, actualPropertyValues[i].EditedValue, $"{property.DeclaringType.Name}.{property.Name}: Expected draft value \"{expectedPropertyValues[i].EditedValue}\" but got \"{actualPropertyValues[i].EditedValue}\"."); - Assert.AreEqual(expectedPropertyValues[i].PublishedValue, actualPropertyValues[i].PublishedValue, $"{property.DeclaringType.Name}.{property.Name}: Expected published value \"{expectedPropertyValues[i].EditedValue}\" but got \"{actualPropertyValues[i].EditedValue}\"."); + // This is not pretty, but since a property value can be a datetime we can't just always compare them as is. + // This is made worse by the fact that PublishedValue is not always set, meaning we can't lump it all into the same if block + if (expectedPropertyValues[i].EditedValue is DateTime expectedEditDateTime) + { + var actualEditDateTime = (DateTime) actualPropertyValues[i].EditedValue; + AssertDateTime(expectedEditDateTime, actualEditDateTime, $"{property.DeclaringType.Name}.{property.Name}: Expected draft value \"{expectedPropertyValues[i].EditedValue}\" but got \"{actualPropertyValues[i].EditedValue}\".", dateDeltaMilliseconds); + } + else + { + Assert.AreEqual(expectedPropertyValues[i].EditedValue, actualPropertyValues[i].EditedValue, $"{property.DeclaringType.Name}.{property.Name}: Expected draft value \"{expectedPropertyValues[i].EditedValue}\" but got \"{actualPropertyValues[i].EditedValue}\"."); + } + + if (expectedPropertyValues[i].PublishedValue is DateTime expectedPublishDateTime) + { + var actualPublishedDateTime = (DateTime) actualPropertyValues[i].PublishedValue; + AssertDateTime(expectedPublishDateTime, actualPublishedDateTime, $"{property.DeclaringType.Name}.{property.Name}: Expected published value \"{expectedPropertyValues[i].PublishedValue}\" but got \"{actualPropertyValues[i].PublishedValue}\".", dateDeltaMilliseconds); + } + else + { + Assert.AreEqual(expectedPropertyValues[i].PublishedValue, actualPropertyValues[i].PublishedValue, $"{property.DeclaringType.Name}.{property.Name}: Expected published value \"{expectedPropertyValues[i].PublishedValue}\" but got \"{actualPropertyValues[i].PublishedValue}\"."); + } } } else if (expected is IDataEditor expectedEditor) @@ -256,5 +277,58 @@ namespace Umbraco.Tests.Integration.Implementations expected?.ToString() ?? "", actual?.ToString() ?? ""); } } + + private static void AssertDateTime(DateTime expected, DateTime actual, string failureMessage, + int dateDeltaMiliseconds = 0) + { + var delta = (actual - expected).TotalMilliseconds; + Assert.IsTrue(Math.Abs(delta) <= dateDeltaMiliseconds, failureMessage); + } + + public void DeleteDirectory(string path) + { + Try(() => + { + if (Directory.Exists(path) == false) return; + foreach (var file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories)) + File.Delete(file); + }); + + Try(() => + { + if (Directory.Exists(path) == false) return; + Directory.Delete(path, true); + }); + } + + public static void TryAssert(Action action, int maxTries = 5, int waitMilliseconds = 200) + { + Try(action, maxTries, waitMilliseconds); + } + + public static void Try(Action action, int maxTries = 5, int waitMilliseconds = 200) + { + Try(action, maxTries, waitMilliseconds); + } + + public static void Try(Action action, int maxTries = 5, int waitMilliseconds = 200) + where T : Exception + { + var tries = 0; + while (true) + { + try + { + action(); + break; + } + catch (T) + { + if (tries++ > maxTries) + throw; + Thread.Sleep(waitMilliseconds); + } + } + } } } diff --git a/src/Umbraco.Tests/Logging/LogviewerTests.cs b/src/Umbraco.Tests.Integration/Logging/LogviewerTests.cs similarity index 96% rename from src/Umbraco.Tests/Logging/LogviewerTests.cs rename to src/Umbraco.Tests.Integration/Logging/LogviewerTests.cs index 04d0150f75..789fd24291 100644 --- a/src/Umbraco.Tests/Logging/LogviewerTests.cs +++ b/src/Umbraco.Tests.Integration/Logging/LogviewerTests.cs @@ -8,8 +8,9 @@ using Microsoft.Extensions.Logging; using Umbraco.Core; using Umbraco.Core.Logging.Viewer; using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.Integration.Implementations; -namespace Umbraco.Tests.Logging +namespace Umbraco.Tests.Integration.Logging { [TestFixture] public class LogviewerTests @@ -34,10 +35,11 @@ namespace Umbraco.Tests.Logging { //Create an example JSON log file to check results //As a one time setup for all tets in this class/fixture - var ioHelper = TestHelper.IOHelper; - var hostingEnv = TestHelper.GetHostingEnvironment(); + var testHelper = new TestHelper(); + var ioHelper = testHelper.IOHelper; + var hostingEnv = testHelper.GetHostingEnvironment(); - var loggingConfiguration = TestHelper.GetLoggingConfiguration(hostingEnv); + var loggingConfiguration = testHelper.GetLoggingConfiguration(hostingEnv); var exampleLogfilePath = Path.Combine(TestContext.CurrentContext.TestDirectory, @"Logging\", _logfileName); _newLogfileDirPath = loggingConfiguration.LogDirectory; diff --git a/src/Umbraco.Tests/Logging/UmbracoTraceLog.UNITTEST.20181112.json b/src/Umbraco.Tests.Integration/Logging/UmbracoTraceLog.UNITTEST.20181112.json similarity index 100% rename from src/Umbraco.Tests/Logging/UmbracoTraceLog.UNITTEST.20181112.json rename to src/Umbraco.Tests.Integration/Logging/UmbracoTraceLog.UNITTEST.20181112.json diff --git a/src/Umbraco.Tests/Logging/logviewer.searches.config.js b/src/Umbraco.Tests.Integration/Logging/logviewer.searches.config.js similarity index 100% rename from src/Umbraco.Tests/Logging/logviewer.searches.config.js rename to src/Umbraco.Tests.Integration/Logging/logviewer.searches.config.js diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/SimilarNodeNameTests.cs b/src/Umbraco.Tests.Integration/Persistence/Repositories/SimilarNodeNameTests.cs deleted file mode 100644 index b60709c8bf..0000000000 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/SimilarNodeNameTests.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System.Linq; -using NUnit.Framework; -using Umbraco.Core.Persistence.Repositories.Implement; - -namespace Umbraco.Tests.Integration.Persistence.Repositories -{ - [TestFixture] - public class SimilarNodeNameTests - { - [TestCase("Alpha", "Alpha", 0)] - [TestCase("Alpha", "ALPHA", +1)] // case is important - [TestCase("Alpha", "Bravo", -1)] - [TestCase("Bravo", "Alpha", +1)] - [TestCase("Alpha (1)", "Alpha (1)", 0)] - [TestCase("Alpha", "Alpha (1)", -1)] - [TestCase("Alpha (1)", "Alpha", +1)] - [TestCase("Alpha (1)", "Alpha (2)", -1)] - [TestCase("Alpha (2)", "Alpha (1)", +1)] - [TestCase("Alpha (2)", "Alpha (10)", -1)] // this is the real stuff - [TestCase("Alpha (10)", "Alpha (2)", +1)] // this is the real stuff - [TestCase("Kilo", "Golf (2)", +1)] - [TestCase("Kilo (1)", "Golf (2)", +1)] - [TestCase("", "", 0)] - [TestCase(null, null, 0)] - public void ComparerTest(string name1, string name2, int expected) - { - var comparer = new SimilarNodeName.Comparer(); - - var result = comparer.Compare(new SimilarNodeName { Name = name1 }, new SimilarNodeName { Name = name2 }); - if (expected == 0) - Assert.AreEqual(0, result); - else if (expected < 0) - Assert.IsTrue(result < 0, "Expected <0 but was " + result); - else if (expected > 0) - Assert.IsTrue(result > 0, "Expected >0 but was " + result); - } - - [Test] - public void OrderByTest() - { - var names = new[] - { - new SimilarNodeName { Id = 1, Name = "Alpha (2)" }, - new SimilarNodeName { Id = 2, Name = "Alpha" }, - new SimilarNodeName { Id = 3, Name = "Golf" }, - new SimilarNodeName { Id = 4, Name = "Zulu" }, - new SimilarNodeName { Id = 5, Name = "Mike" }, - new SimilarNodeName { Id = 6, Name = "Kilo (1)" }, - new SimilarNodeName { Id = 7, Name = "Yankee" }, - new SimilarNodeName { Id = 8, Name = "Kilo" }, - new SimilarNodeName { Id = 9, Name = "Golf (2)" }, - new SimilarNodeName { Id = 10, Name = "Alpha (1)" }, - }; - - var ordered = names.OrderBy(x => x, new SimilarNodeName.Comparer()).ToArray(); - - var i = 0; - Assert.AreEqual(2, ordered[i++].Id); - Assert.AreEqual(10, ordered[i++].Id); - Assert.AreEqual(1, ordered[i++].Id); - Assert.AreEqual(3, ordered[i++].Id); - Assert.AreEqual(9, ordered[i++].Id); - Assert.AreEqual(8, ordered[i++].Id); - Assert.AreEqual(6, ordered[i++].Id); - Assert.AreEqual(5, ordered[i++].Id); - Assert.AreEqual(7, ordered[i++].Id); - Assert.AreEqual(4, ordered[i++].Id); - } - - [TestCase(0, "Charlie", "Charlie")] - [TestCase(0, "Zulu", "Zulu (1)")] - [TestCase(0, "Golf", "Golf (1)")] - [TestCase(0, "Kilo", "Kilo (2)")] - [TestCase(0, "Alpha", "Alpha (3)")] - [TestCase(0, "Kilo (1)", "Kilo (1) (1)")] // though... we might consider "Kilo (2)" - [TestCase(6, "Kilo (1)", "Kilo (1)")] // because of the id - [TestCase(0, "alpha", "alpha (3)")] - [TestCase(0, "", " (1)")] - [TestCase(0, null, " (1)")] - public void Test(int nodeId, string nodeName, string expected) - { - var names = new[] - { - new SimilarNodeName { Id = 1, Name = "Alpha (2)" }, - new SimilarNodeName { Id = 2, Name = "Alpha" }, - new SimilarNodeName { Id = 3, Name = "Golf" }, - new SimilarNodeName { Id = 4, Name = "Zulu" }, - new SimilarNodeName { Id = 5, Name = "Mike" }, - new SimilarNodeName { Id = 6, Name = "Kilo (1)" }, - new SimilarNodeName { Id = 7, Name = "Yankee" }, - new SimilarNodeName { Id = 8, Name = "Kilo" }, - new SimilarNodeName { Id = 9, Name = "Golf (2)" }, - new SimilarNodeName { Id = 10, Name = "Alpha (1)" }, - }; - - Assert.AreEqual(expected, SimilarNodeName.GetUniqueName(names, nodeId, nodeName)); - } - - [Test] - [Explicit("This test fails! We need to fix up the logic")] - public void TestMany() - { - var names = new[] - { - new SimilarNodeName { Id = 1, Name = "Alpha (2)" }, - new SimilarNodeName { Id = 2, Name = "Test" }, - new SimilarNodeName { Id = 3, Name = "Test (1)" }, - new SimilarNodeName { Id = 4, Name = "Test (2)" }, - new SimilarNodeName { Id = 22, Name = "Test (1) (1)" }, - }; - - //fixme - this will yield "Test (2)" which is already in use - Assert.AreEqual("Test (3)", SimilarNodeName.GetUniqueName(names, 0, "Test")); - } - } -} diff --git a/src/Umbraco.Tests.Integration/RuntimeTests.cs b/src/Umbraco.Tests.Integration/RuntimeTests.cs index 87b1bdd198..edbecad51e 100644 --- a/src/Umbraco.Tests.Integration/RuntimeTests.cs +++ b/src/Umbraco.Tests.Integration/RuntimeTests.cs @@ -12,6 +12,7 @@ using Umbraco.Core.Composing; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Runtime; using Umbraco.Extensions; +using Umbraco.Infrastructure.Composing; using Umbraco.Tests.Common; using Umbraco.Tests.Integration.Extensions; using Umbraco.Tests.Integration.Implementations; @@ -43,10 +44,8 @@ namespace Umbraco.Tests.Integration [Test] public void Boot_Core_Runtime() { - // LightInject / Umbraco - var container = UmbracoServiceProviderFactory.CreateServiceContainer(); - var serviceProviderFactory = new UmbracoServiceProviderFactory(container, false); - var umbracoContainer = serviceProviderFactory.GetContainer(); + // TODO: MSDI - cleanup after initial merge. + var umbracoContainer = new ServiceCollectionRegistryAdapter(new ServiceCollection()); // Special case since we are not using the Generic Host, we need to manually add an AspNetCore service to the container umbracoContainer.Register(x => Mock.Of()); @@ -56,22 +55,6 @@ namespace Umbraco.Tests.Integration var globalSettings = new GlobalSettings(); var connectionStrings = new ConnectionStrings(); - // Create the core runtime - var coreRuntime = new CoreRuntime(globalSettings, connectionStrings, testHelper.GetUmbracoVersion(), - testHelper.IOHelper, testHelper.ConsoleLoggerFactory, testHelper.Profiler, testHelper.UmbracoBootPermissionChecker, - testHelper.GetHostingEnvironment(), testHelper.GetBackOfficeInfo(), testHelper.DbProviderFactoryCreator, - testHelper.MainDom, testHelper.GetTypeFinder(), AppCaches.NoCache); - - // boot it! - var factory = coreRuntime.Configure(umbracoContainer); - - Assert.IsTrue(coreRuntime.MainDom.IsMainDom); - Assert.IsNull(coreRuntime.State.BootFailedException); - Assert.AreEqual(RuntimeLevel.Install, coreRuntime.State.Level); - Assert.IsTrue(MyComposer.IsComposed); - Assert.IsFalse(MyComponent.IsInit); - Assert.IsFalse(MyComponent.IsTerminated); - // TODO: found these registration were necessary here (as we haven't called the HostBuilder?), as dependencies for ComponentCollection // are not resolved. Need to check this if these explicit registrations are the best way to handle this. var contentSettings = new ContentSettings(); @@ -89,13 +72,28 @@ namespace Umbraco.Tests.Integration umbracoContainer.Register(x => Options.Create(userPasswordConfigurationSettings)); umbracoContainer.Register(x => Options.Create(webRoutingSettings)); umbracoContainer.Register(typeof(ILogger<>), typeof(Logger<>), Lifetime.Singleton); + + // Create the core runtime + var coreRuntime = new CoreRuntime(globalSettings, connectionStrings, testHelper.GetUmbracoVersion(), + testHelper.IOHelper, testHelper.ConsoleLoggerFactory, testHelper.Profiler, testHelper.UmbracoBootPermissionChecker, + testHelper.GetHostingEnvironment(), testHelper.GetBackOfficeInfo(), testHelper.DbProviderFactoryCreator, + testHelper.MainDom, testHelper.GetTypeFinder(), AppCaches.NoCache); + + coreRuntime.Configure(umbracoContainer); + + Assert.IsTrue(coreRuntime.MainDom.IsMainDom); + Assert.IsNull(coreRuntime.State.BootFailedException); + Assert.AreEqual(RuntimeLevel.Install, coreRuntime.State.Level); + Assert.IsTrue(MyComposer.IsComposed); + Assert.IsFalse(MyComponent.IsInit); + Assert.IsFalse(MyComponent.IsTerminated); + + coreRuntime.Start(); Assert.IsTrue(MyComponent.IsInit); Assert.IsFalse(MyComponent.IsTerminated); - Assertions.AssertContainer(umbracoContainer.Container, reportOnly: true); // TODO Change that to false eventually when we clean up the container - coreRuntime.Terminate(); Assert.IsTrue(MyComponent.IsTerminated); @@ -107,11 +105,10 @@ namespace Umbraco.Tests.Integration [Test] public async Task AddUmbracoCore() { - var umbracoContainer = UmbracoIntegrationTest.CreateUmbracoContainer(out var serviceProviderFactory); var testHelper = new TestHelper(); var hostBuilder = new HostBuilder() - .UseUmbraco(serviceProviderFactory) + .UseUmbraco() .ConfigureServices((hostContext, services) => { var webHostEnvironment = testHelper.GetWebHostEnvironment(); @@ -120,7 +117,10 @@ namespace Umbraco.Tests.Integration // Add it! services.AddUmbracoConfiguration(hostContext.Configuration); - services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(), hostContext.Configuration,out _); + + // TODO: MSDI - cleanup after initial merge. + var register = new ServiceCollectionRegistryAdapter(services); + services.AddUmbracoCore(webHostEnvironment, register, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(), hostContext.Configuration,out _); }); var host = await hostBuilder.StartAsync(); @@ -147,11 +147,10 @@ namespace Umbraco.Tests.Integration [Test] public async Task UseUmbracoCore() { - var umbracoContainer = UmbracoIntegrationTest.CreateUmbracoContainer(out var serviceProviderFactory); var testHelper = new TestHelper(); var hostBuilder = new HostBuilder() - .UseUmbraco(serviceProviderFactory) + .UseUmbraco() .ConfigureServices((hostContext, services) => { var webHostEnvironment = testHelper.GetWebHostEnvironment(); @@ -160,7 +159,9 @@ namespace Umbraco.Tests.Integration // Add it! services.AddUmbracoConfiguration(hostContext.Configuration); - services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(),hostContext.Configuration, out _); + // TODO: MSDI - cleanup after initial merge. + var register = new ServiceCollectionRegistryAdapter(services); + services.AddUmbracoCore(webHostEnvironment, register, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(),hostContext.Configuration, out _); }); var host = await hostBuilder.StartAsync(); diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs index f7e451b03f..62585e1423 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs @@ -4,6 +4,7 @@ using Umbraco.Core.Composing.LightInject; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Runtime; using Umbraco.Extensions; +using Umbraco.Infrastructure.Composing; using Umbraco.Tests.Integration.Implementations; using Umbraco.Tests.Integration.Testing; using Umbraco.Web.Common.Builder; @@ -18,15 +19,16 @@ namespace Umbraco.Tests.Integration.TestServerTest /// /// public static IUmbracoBuilder WithTestCore(this IUmbracoBuilder builder, TestHelper testHelper, - LightInjectContainer container, Action dbInstallEventHandler) { return builder.AddWith(nameof(global::Umbraco.Web.Common.Builder.UmbracoBuilderExtensions.WithCore), () => { + // TODO: MSDI - cleanup after initial merge. + var register = new ServiceCollectionRegistryAdapter(builder.Services); builder.Services.AddUmbracoCore( builder.WebHostEnvironment, - container, + register, typeof(UmbracoBuilderExtensions).Assembly, AppCaches.NoCache, // Disable caches in integration tests testHelper.GetLoggingConfiguration(), diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs index aefb5679e5..a7ea7e0315 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using NUnit.Framework; using Umbraco.Composing; using Umbraco.Core; @@ -133,7 +134,7 @@ namespace Umbraco.Tests.Integration.TestServerTest var umbracoBuilder = services.AddUmbraco(TestHelper.GetWebHostEnvironment(), Configuration); umbracoBuilder .WithConfiguration() - .WithTestCore(TestHelper, UmbracoContainer, UseTestLocalDb) // This is the important one! + .WithTestCore(TestHelper, UseTestLocalDb) // This is the important one! .WithWebComponents() .WithRuntimeMinifier() .WithBackOffice() diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index 461afeabb7..3da8c8d7a5 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -35,6 +35,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Serilog; using Umbraco.Core.Logging.Serilog; +using Umbraco.Infrastructure.Composing; using ConnectionStrings = Umbraco.Core.Configuration.Models.ConnectionStrings; using ILogger = Microsoft.Extensions.Logging.ILogger; @@ -51,14 +52,6 @@ namespace Umbraco.Tests.Integration.Testing [NonParallelizable] public abstract class UmbracoIntegrationTest { - public static LightInjectContainer CreateUmbracoContainer(out UmbracoServiceProviderFactory serviceProviderFactory) - { - var container = UmbracoServiceProviderFactory.CreateServiceContainer(); - serviceProviderFactory = new UmbracoServiceProviderFactory(container, false); - var umbracoContainer = serviceProviderFactory.GetContainer(); - return umbracoContainer; - } - private List _testTeardown = null; private List _fixtureTeardown = new List(); @@ -134,16 +127,13 @@ namespace Umbraco.Tests.Integration.Testing /// public virtual IHostBuilder CreateHostBuilder() { - UmbracoContainer = CreateUmbracoContainer(out var serviceProviderFactory); - _serviceProviderFactory = serviceProviderFactory; - var hostBuilder = Host.CreateDefaultBuilder() // IMPORTANT: We Cannot use UseStartup, there's all sorts of threads about this with testing. Although this can work // if you want to setup your tests this way, it is a bit annoying to do that as the WebApplicationFactory will // create separate Host instances. So instead of UseStartup, we just call ConfigureServices/Configure ourselves, // and in the case of the UmbracoTestServerTestBase it will use the ConfigureWebHost to Configure the IApplicationBuilder directly. //.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(GetType()); }) - .UseUmbraco(_serviceProviderFactory) + .UseUmbraco() .ConfigureAppConfiguration((context, configBuilder) => { context.HostingEnvironment = TestHelper.GetWebHostEnvironment(); @@ -258,9 +248,11 @@ namespace Umbraco.Tests.Integration.Testing // Add it! services.AddUmbracoConfiguration(Configuration); + // TODO: MSDI - cleanup after initial merge. + var register = new ServiceCollectionRegistryAdapter(services); services.AddUmbracoCore( webHostEnvironment, - UmbracoContainer, + register, GetType().Assembly, AppCaches.NoCache, // Disable caches for integration tests TestHelper.GetLoggingConfiguration(), @@ -443,10 +435,7 @@ namespace Umbraco.Tests.Integration.Testing #endregion #region Common services - - protected LightInjectContainer UmbracoContainer { get; private set; } - private UmbracoServiceProviderFactory _serviceProviderFactory; - + protected virtual T GetRequiredService() => Services.GetRequiredService(); public Dictionary InMemoryConfiguration { get; } = new Dictionary(); @@ -455,7 +444,7 @@ namespace Umbraco.Tests.Integration.Testing public TestHelper TestHelper = new TestHelper(); - protected string TestDBConnectionString { get; private set; } + protected virtual string TestDBConnectionString { get; private set; } protected virtual Action CustomTestSetup => services => { }; diff --git a/src/Umbraco.Tests.Integration/Mapping/ContentTypeModelMappingTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Core/Mapping/ContentTypeModelMappingTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Mapping/ContentTypeModelMappingTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Core/Mapping/ContentTypeModelMappingTests.cs index 96e49e79e9..03e8f04cfc 100644 --- a/src/Umbraco.Tests.Integration/Mapping/ContentTypeModelMappingTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Core/Mapping/ContentTypeModelMappingTests.cs @@ -13,7 +13,7 @@ using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; using Umbraco.Web.Models.ContentEditing; -namespace Umbraco.Tests.Models.Mapping +namespace Umbraco.Tests.Integration.Umbraco.Core.Mapping { [TestFixture] [UmbracoTest(Mapper = true, Database = UmbracoTestOptions.Database.NewSchemaPerTest)] @@ -756,7 +756,7 @@ namespace Umbraco.Tests.Models.Mapping Alias = "umbracoUrlName", Name = "Slug", Description = "", Mandatory = false, SortOrder = 1, DataTypeId = -88 }); ContentTypeBuilder.EnsureAllIds(ctMain, 8888); - var ctChild1 = ContentTypeBuilder.CreateSimpleContentType("child1", "Child 1", ctMain, true); + var ctChild1 = ContentTypeBuilder.CreateSimpleContentType("child1", "Child 1", ctMain, randomizeAliases: true); ctChild1.AddPropertyType(new PropertyType(ShortStringHelper, Constants.PropertyEditors.Aliases.TextBox, ValueStorageType.Ntext) { Alias = "someProperty", @@ -767,7 +767,7 @@ namespace Umbraco.Tests.Models.Mapping DataTypeId = -88 }, "Another tab"); ContentTypeBuilder.EnsureAllIds(ctChild1, 7777); - var contentType = ContentTypeBuilder.CreateSimpleContentType("child2", "Child 2", ctChild1, true, "CustomGroup"); + var contentType = ContentTypeBuilder.CreateSimpleContentType("child2", "Child 2", ctChild1, randomizeAliases: true, propertyGroupName: "CustomGroup"); //not assigned to tab contentType.AddPropertyType(new PropertyType(ShortStringHelper, Constants.PropertyEditors.Aliases.TextBox, ValueStorageType.Ntext) { diff --git a/src/Umbraco.Tests.Integration/Mapping/UmbracoMapperTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Core/Mapping/UmbracoMapperTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Mapping/UmbracoMapperTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Core/Mapping/UmbracoMapperTests.cs index 2b26c862f0..4028889b01 100644 --- a/src/Umbraco.Tests.Integration/Mapping/UmbracoMapperTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Core/Mapping/UmbracoMapperTests.cs @@ -13,7 +13,7 @@ using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; using Umbraco.Web.Models.ContentEditing; -namespace Umbraco.Tests.Integration.Mapping +namespace Umbraco.Tests.Integration.Umbraco.Core.Mapping { [TestFixture] [UmbracoTest(Mapper = true, Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Mapping/UserModelMapperTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Core/Mapping/UserModelMapperTests.cs similarity index 97% rename from src/Umbraco.Tests.Integration/Mapping/UserModelMapperTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Core/Mapping/UserModelMapperTests.cs index e24a8a74bc..f8c276d429 100644 --- a/src/Umbraco.Tests.Integration/Mapping/UserModelMapperTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Core/Mapping/UserModelMapperTests.cs @@ -8,7 +8,7 @@ using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; using Umbraco.Web.Models.ContentEditing; -namespace Umbraco.Tests.Models.Mapping +namespace Umbraco.Tests.Integration.Umbraco.Core.Mapping { [TestFixture] [UmbracoTest(Mapper = true, Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Packaging/CreatedPackagesRepositoryTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Core/Packaging/CreatedPackagesRepositoryTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Packaging/CreatedPackagesRepositoryTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Core/Packaging/CreatedPackagesRepositoryTests.cs index 2500dd97a4..6f3702765e 100644 --- a/src/Umbraco.Tests.Integration/Packaging/CreatedPackagesRepositoryTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Core/Packaging/CreatedPackagesRepositoryTests.cs @@ -15,7 +15,7 @@ using Umbraco.Core.Services; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Packaging +namespace Umbraco.Tests.Integration.Umbraco.Core.Packaging { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)] diff --git a/src/Umbraco.Tests.Integration/Packaging/Packages/Document_Type_Picker_1.1.umb b/src/Umbraco.Tests.Integration/Umbraco.Core/Packaging/Packages/Document_Type_Picker_1.1.umb similarity index 100% rename from src/Umbraco.Tests.Integration/Packaging/Packages/Document_Type_Picker_1.1.umb rename to src/Umbraco.Tests.Integration/Umbraco.Core/Packaging/Packages/Document_Type_Picker_1.1.umb diff --git a/src/Umbraco.Tests.Integration/Services/SectionServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Core/Services/SectionServiceTests.cs similarity index 97% rename from src/Umbraco.Tests.Integration/Services/SectionServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Core/Services/SectionServiceTests.cs index f34ea32cff..24a4e8d772 100644 --- a/src/Umbraco.Tests.Integration/Services/SectionServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Core/Services/SectionServiceTests.cs @@ -8,7 +8,7 @@ using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; using Umbraco.Web.Services; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Core.Services { /// /// Tests covering the SectionService diff --git a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoBulkInsertTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoBulkInsertTests.cs similarity index 77% rename from src/Umbraco.Tests/Persistence/NPocoTests/NPocoBulkInsertTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoBulkInsertTests.cs index 5a0e4b6ed2..dd66efb47a 100644 --- a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoBulkInsertTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoBulkInsertTests.cs @@ -6,35 +6,43 @@ using System.Text.RegularExpressions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using NUnit.Framework; +using Umbraco.Core.Logging; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; +using Umbraco.Tests.Integration.Implementations; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.NPocoTests +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.NPocoTests { // FIXME: npoco - is this still appropriate? // [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class NPocoBulkInsertTests : TestWithDatabaseBase + public class NPocoBulkInsertTests : UmbracoIntegrationTest { + private TestHelper _testHelper = new TestHelper(); + private IProfilingLogger ProfilingLogger => _testHelper.ProfilingLogger; - - [NUnit.Framework.Ignore("Ignored because you need to configure your own SQL Server to test thsi with")] + [NUnit.Framework.Ignore("Ignored because you need to configure your own SQL Server to test this with")] [Test] public void Can_Bulk_Insert_Native_Sql_Server_Bulk_Inserts() { // create the db // prob not what we want, this is not a real database, but hey, the test is ignored anyways // we'll fix this when we have proper testing infrastructure - var dbSqlServer = TestObjects.GetUmbracoSqlServerDatabase(new NullLogger()); + // var dbSqlServer = TestObjects.GetUmbracoSqlServerDatabase(new NullLogger()); + var provider = ScopeProvider; + using (var scope = ScopeProvider.CreateScope()) + { + // Still no what we want, but look above. + var dbSqlServer = scope.Database; + //drop the table + dbSqlServer.Execute("DROP TABLE [umbracoServer]"); - //drop the table - dbSqlServer.Execute("DROP TABLE [umbracoServer]"); - - //re-create it - dbSqlServer.Execute(@"CREATE TABLE [umbracoServer]( + //re-create it + dbSqlServer.Execute(@"CREATE TABLE [umbracoServer]( [id] [int] IDENTITY(1,1) NOT NULL, [address] [nvarchar](500) NOT NULL, [computerName] [nvarchar](255) NOT NULL, @@ -47,27 +55,28 @@ namespace Umbraco.Tests.Persistence.NPocoTests [id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] )"); - var data = new List(); - for (var i = 0; i < 1000; i++) - { - data.Add(new ServerRegistrationDto + var data = new List(); + for (var i = 0; i < 1000; i++) { - ServerAddress = "address" + i, - ServerIdentity = "computer" + i, - DateRegistered = DateTime.Now, - IsActive = true, - DateAccessed = DateTime.Now - }); - } + data.Add(new ServerRegistrationDto + { + ServerAddress = "address" + i, + ServerIdentity = "computer" + i, + DateRegistered = DateTime.Now, + IsActive = true, + DateAccessed = DateTime.Now + }); + } - using (var tr = dbSqlServer.GetTransaction()) - { - dbSqlServer.BulkInsertRecords(data); - tr.Complete(); - } + using (var tr = dbSqlServer.GetTransaction()) + { + dbSqlServer.BulkInsertRecords(data); + tr.Complete(); + } - // Assert - Assert.That(dbSqlServer.ExecuteScalar("SELECT COUNT(*) FROM umbracoServer"), Is.EqualTo(1000)); + // Assert + Assert.That(dbSqlServer.ExecuteScalar("SELECT COUNT(*) FROM umbracoServer"), Is.EqualTo(1000)); + } } [Test] diff --git a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoFetchTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoFetchTests.cs similarity index 98% rename from src/Umbraco.Tests/Persistence/NPocoTests/NPocoFetchTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoFetchTests.cs index 9ee50d1230..58429ed80e 100644 --- a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoFetchTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoFetchTests.cs @@ -4,19 +4,18 @@ using System.Linq; using NPoco; using NUnit.Framework; using Umbraco.Core.Persistence; -using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.NPocoTests +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.NPocoTests { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, WithApplication = true)] - public class NPocoFetchTests : TestWithDatabaseBase + public class NPocoFetchTests : UmbracoIntegrationTest { - protected override void Initialize() + [SetUp] + protected void SeedDatabase() { - base.Initialize(); - using (var scope = ScopeProvider.CreateScope()) { InsertData(scope.Database); diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/AuditRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/AuditRepositoryTest.cs similarity index 98% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/AuditRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/AuditRepositoryTest.cs index 24316eb931..d62e0623b1 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/AuditRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/AuditRepositoryTest.cs @@ -10,7 +10,7 @@ using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; using Microsoft.Extensions.Logging; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, Logger = UmbracoTestOptions.Logger.Console)] diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/ContentTypeRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ContentTypeRepositoryTest.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/ContentTypeRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ContentTypeRepositoryTest.cs index f265519e28..757e79eef3 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/ContentTypeRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ContentTypeRepositoryTest.cs @@ -24,7 +24,7 @@ using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.Testing; using Umbraco.Web.Models.ContentEditing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Mapper = true, Database = UmbracoTestOptions.Database.NewSchemaPerTest)] @@ -519,8 +519,8 @@ namespace Umbraco.Tests.Persistence.Repositories { var repository = ContentTypeRepository; var ctMain = ContentTypeBuilder.CreateSimpleContentType(defaultTemplateId:0); - var ctChild1 = ContentTypeBuilder.CreateSimpleContentType("child1", "Child 1", ctMain, true, defaultTemplateId:0); - var ctChild2 = ContentTypeBuilder.CreateSimpleContentType("child2", "Child 2", ctChild1, true, defaultTemplateId:0); + var ctChild1 = ContentTypeBuilder.CreateSimpleContentType("child1", "Child 1", ctMain, randomizeAliases: true, defaultTemplateId: 0); + var ctChild2 = ContentTypeBuilder.CreateSimpleContentType("child2", "Child 2", ctChild1, randomizeAliases: true, defaultTemplateId: 0); repository.Save(ctMain); repository.Save(ctChild1); diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs index 6d991117a1..5b39eb9864 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs @@ -9,7 +9,7 @@ using Umbraco.Core.Services; using Umbraco.Tests.Integration.Testing; using Umbraco.Web.PropertyEditors; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/DictionaryRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DictionaryRepositoryTest.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/DictionaryRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DictionaryRepositoryTest.cs index 4d5bdac6b4..105d7520fd 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/DictionaryRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DictionaryRepositoryTest.cs @@ -9,7 +9,7 @@ using Umbraco.Core.Services; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/DocumentRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DocumentRepositoryTest.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/DocumentRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DocumentRepositoryTest.cs index 7dff775c8f..5cf402be26 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/DocumentRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DocumentRepositoryTest.cs @@ -5,22 +5,20 @@ using Microsoft.Extensions.Logging; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; +using Umbraco.Core.Configuration.Models; +using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Scoping; using Umbraco.Core.Services; -using Umbraco.Tests.Testing; -using Umbraco.Web.PropertyEditors; -using Umbraco.Core.Configuration.Models; -using Umbraco.Core.IO; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; +using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] @@ -36,8 +34,6 @@ namespace Umbraco.Tests.Persistence.Repositories private IContentTypeService ContentTypeService => GetRequiredService(); private IFileService FileService => GetRequiredService(); private IDataTypeService DataTypeService => GetRequiredService(); - private ILocalizedTextService LocalizedTextService => GetRequiredService(); - private ILocalizationService LocalizationService => GetRequiredService(); private IFileSystems FileSystems => GetRequiredService(); [SetUp] @@ -45,6 +41,9 @@ namespace Umbraco.Tests.Persistence.Repositories { CreateTestData(); + // TODO: remove this once IPublishedSnapShotService has been implemented with nucache. + global::Umbraco.Core.Services.Implement.ContentTypeService.ClearScopeEvents(); + ContentRepositoryBase.ThrowOnWarning = true; } diff --git a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DomainRepositoryTest.cs similarity index 56% rename from src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DomainRepositoryTest.cs index e09587fa8c..b6faa4e31d 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DomainRepositoryTest.cs @@ -1,66 +1,48 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Data; using System.Linq; using Microsoft.Extensions.Logging; -using Moq; using NUnit.Framework; +using Umbraco.Core.Cache; using Umbraco.Core.Configuration.Models; -using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Models; +using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; -using Umbraco.Core.PropertyEditors; using Umbraco.Core.Scoping; using Umbraco.Tests.Common.Builders; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class DomainRepositoryTest : TestWithDatabaseBase + public class DomainRepositoryTest : UmbracoIntegrationTest { - private DomainRepository CreateRepository(IScopeProvider provider, out ContentTypeRepository contentTypeRepository, out DocumentRepository documentRepository, out LanguageRepository languageRepository) - { - var globalSettings = Microsoft.Extensions.Options.Options.Create(new GlobalSettings()); + private ILanguageRepository LanguageRepository => GetRequiredService(); + private IDocumentRepository DocumentRepository => GetRequiredService(); + private IContentTypeRepository ContentTypeRepository => GetRequiredService(); + private DomainRepository CreateRepository(IScopeProvider provider) + { var accessor = (IScopeAccessor) provider; - var templateRepository = new TemplateRepository(accessor, Core.Cache.AppCaches.Disabled, LoggerFactory.CreateLogger(), TestObjects.GetFileSystemsMock(), IOHelper, ShortStringHelper); - var tagRepository = new TagRepository(accessor, Core.Cache.AppCaches.Disabled, LoggerFactory.CreateLogger()); - var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches, ShortStringHelper); - languageRepository = new LanguageRepository(accessor, Core.Cache.AppCaches.Disabled, LoggerFactory.CreateLogger(), globalSettings); - contentTypeRepository = new ContentTypeRepository(accessor, Core.Cache.AppCaches.Disabled, LoggerFactory.CreateLogger(), commonRepository, languageRepository, ShortStringHelper); - var relationTypeRepository = new RelationTypeRepository(accessor, Core.Cache.AppCaches.Disabled, LoggerFactory.CreateLogger()); - var entityRepository = new EntityRepository(accessor); - var relationRepository = new RelationRepository(accessor, LoggerFactory.CreateLogger(), relationTypeRepository, entityRepository); - var propertyEditors = new Lazy(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty()))); - var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty()); - documentRepository = new DocumentRepository(accessor, Core.Cache.AppCaches.Disabled, LoggerFactory.CreateLogger(), LoggerFactory, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences, DataTypeService); - var domainRepository = new DomainRepository(accessor, Core.Cache.AppCaches.Disabled, LoggerFactory.CreateLogger()); + var domainRepository = new DomainRepository(accessor, AppCaches.NoCache, LoggerFactory.CreateLogger()); return domainRepository; } private int CreateTestData(string isoName, out ContentType ct) { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; - - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); - var globalSettings = new GlobalSettings(); var lang = new Language(globalSettings, isoName); - langRepo.Save(lang); + LanguageRepository.Save(lang); - ct = MockedContentTypes.CreateBasicContentType("test", "Test"); - contentTypeRepo.Save(ct); + ct = ContentTypeBuilder.CreateBasicContentType("test", "Test"); + ContentTypeRepository.Save(ct); var content = new Content("test", -1, ct) { CreatorId = 0, WriterId = 0 }; - documentRepo.Save(content); + DocumentRepository.Save(content); scope.Complete(); return content.Id; } @@ -72,17 +54,13 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; + var repo = CreateRepository(provider); - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); - - var lang = langRepo.GetByIsoCode("en-AU"); - var content = documentRepo.Get(contentId); + var lang = LanguageRepository.GetByIsoCode("en-AU"); + var content = DocumentRepository.Get(contentId); var domain = (IDomain)new UmbracoDomain("test.com") { RootContentId = content.Id, LanguageId = lang.Id }; repo.Save(domain); @@ -106,16 +84,12 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; + var repo = CreateRepository(provider); - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); - - var content = documentRepo.Get(contentId); + var content = DocumentRepository.Get(contentId); var domain = (IDomain)new UmbracoDomain("test.com") { RootContentId = content.Id }; repo.Save(domain); @@ -138,17 +112,13 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; + var repo = CreateRepository(provider); - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); - - var lang = langRepo.GetByIsoCode("en-AU"); - var content = documentRepo.Get(contentId); + var lang = LanguageRepository.GetByIsoCode("en-AU"); + var content = DocumentRepository.Get(contentId); var domain1 = (IDomain)new UmbracoDomain("test.com") { RootContentId = content.Id, LanguageId = lang.Id }; repo.Save(domain1); @@ -165,17 +135,13 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; + var repo = CreateRepository(provider); - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); - - var lang = langRepo.GetByIsoCode("en-AU"); - var content = documentRepo.Get(contentId); + var lang = LanguageRepository.GetByIsoCode("en-AU"); + var content = DocumentRepository.Get(contentId); var domain = (IDomain)new UmbracoDomain("test.com") { RootContentId = content.Id, LanguageId = lang.Id }; repo.Save(domain); @@ -196,24 +162,20 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId1 = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; + var repo = CreateRepository(provider); - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); - - var content1 = documentRepo.Get(contentId1); + var content1 = DocumentRepository.Get(contentId1); //more test data - var lang1 = langRepo.GetByIsoCode("en-AU"); + var lang1 = LanguageRepository.GetByIsoCode("en-AU"); var globalSettings = new GlobalSettings(); var lang2 = new Language(globalSettings, "es"); - langRepo.Save(lang2); + LanguageRepository.Save(lang2); var content2 = new Content("test", -1, ct) { CreatorId = 0, WriterId = 0 }; - documentRepo.Save(content2); + DocumentRepository.Save(content2); var domain = (IDomain)new UmbracoDomain("test.com") { RootContentId = content1.Id, LanguageId = lang1.Id }; @@ -244,17 +206,13 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; + var repo = CreateRepository(provider); - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); - - var lang = langRepo.GetByIsoCode("en-AU"); - var content = documentRepo.Get(contentId); + var lang = LanguageRepository.GetByIsoCode("en-AU"); + var content = DocumentRepository.Get(contentId); for (int i = 0; i < 10; i++) { @@ -274,17 +232,13 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; + var repo = CreateRepository(provider); - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); - - var lang = langRepo.GetByIsoCode("en-AU"); - var content = documentRepo.Get(contentId); + var lang = LanguageRepository.GetByIsoCode("en-AU"); + var content = DocumentRepository.Get(contentId); for (int i = 0; i < 10; i++) { @@ -304,17 +258,13 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; + var repo = CreateRepository(provider); - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); - - var lang = langRepo.GetByIsoCode("en-AU"); - var content = documentRepo.Get(contentId); + var lang = LanguageRepository.GetByIsoCode("en-AU"); + var content = DocumentRepository.Get(contentId); for (int i = 0; i < 10; i++) { @@ -334,17 +284,13 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; + var repo = CreateRepository(provider); - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); - - var lang = langRepo.GetByIsoCode("en-AU"); - var content = documentRepo.Get(contentId); + var lang = LanguageRepository.GetByIsoCode("en-AU"); + var content = DocumentRepository.Get(contentId); var ids = new List(); for (int i = 0; i < 10; i++) @@ -366,17 +312,13 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; + var repo = CreateRepository(provider); - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); - - var lang = langRepo.GetByIsoCode("en-AU"); - var content = documentRepo.Get(contentId); + var lang = LanguageRepository.GetByIsoCode("en-AU"); + var content = DocumentRepository.Get(contentId); for (int i = 0; i < 10; i++) { @@ -400,25 +342,21 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; - - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); + var repo = CreateRepository(provider); var contentItems = new List(); - var lang = langRepo.GetByIsoCode("en-AU"); - contentItems.Add(documentRepo.Get(contentId)); + var lang = LanguageRepository.GetByIsoCode("en-AU"); + contentItems.Add(DocumentRepository.Get(contentId)); //more test data (3 content items total) for (int i = 0; i < 2; i++) { var c = new Content("test" + i, -1, ct) { CreatorId = 0, WriterId = 0 }; - documentRepo.Save(c); + DocumentRepository.Save(c); contentItems.Add(c); } @@ -449,25 +387,21 @@ namespace Umbraco.Tests.Persistence.Repositories ContentType ct; var contentId = CreateTestData("en-AU", out ct); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - DocumentRepository documentRepo; - LanguageRepository langRepo; - ContentTypeRepository contentTypeRepo; - - var repo = CreateRepository(provider, out contentTypeRepo, out documentRepo, out langRepo); + var repo = CreateRepository(provider); var contentItems = new List(); - var lang = langRepo.GetByIsoCode("en-AU"); - contentItems.Add(documentRepo.Get(contentId)); + var lang = LanguageRepository.GetByIsoCode("en-AU"); + contentItems.Add(DocumentRepository.Get(contentId)); //more test data (3 content items total) for (int i = 0; i < 2; i++) { var c = new Content("test" + i, -1, ct) { CreatorId = 0, WriterId = 0 }; - documentRepo.Save(c); + DocumentRepository.Save(c); contentItems.Add(c); } diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/EntityRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/EntityRepositoryTest.cs similarity index 97% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/EntityRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/EntityRepositoryTest.cs index c0da3ec8cd..3fb518661c 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/EntityRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/EntityRepositoryTest.cs @@ -11,7 +11,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Mapper = true, Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/KeyValueRepositoryTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/KeyValueRepositoryTests.cs similarity index 96% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/KeyValueRepositoryTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/KeyValueRepositoryTests.cs index 1b5b40cf3c..93b6ee43f5 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/KeyValueRepositoryTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/KeyValueRepositoryTests.cs @@ -8,7 +8,7 @@ using Umbraco.Core.Scoping; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/LanguageRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/LanguageRepositoryTest.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/LanguageRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/LanguageRepositoryTest.cs index 0b699823cb..aa9c0ddc86 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/LanguageRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/LanguageRepositoryTest.cs @@ -13,7 +13,7 @@ using Umbraco.Core.Services; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/MacroRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MacroRepositoryTest.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/MacroRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MacroRepositoryTest.cs index 901d905686..e68f9584fb 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/MacroRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MacroRepositoryTest.cs @@ -10,7 +10,7 @@ using Umbraco.Core.Scoping; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MediaRepositoryTest.cs similarity index 81% rename from src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MediaRepositoryTest.cs index d5efa77606..dfc25c7e50 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MediaRepositoryTest.cs @@ -15,30 +15,38 @@ using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Scoping; using Umbraco.Core.Services; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Tests.Common.Builders; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class MediaRepositoryTest : TestWithDatabaseBase + public class MediaRepositoryTest : UmbracoIntegrationTest { - public override void SetUp() - { - base.SetUp(); + private IMediaService MediaService => GetRequiredService(); + private IMediaTypeService MediaTypeService => GetRequiredService(); + private ITemplateRepository TemplateRepository => GetRequiredService(); + private IDataTypeService DataTypeService => GetRequiredService(); + // Makes handing IDs easier, these are set by CreateTestData + private Media _testFolder; + private Media _testImage; + private Media _testFile; + + [SetUp] + public void SetUpTestData() + { CreateTestData(); } private MediaRepository CreateRepository(IScopeProvider provider, out MediaTypeRepository mediaTypeRepository, AppCaches appCaches = null) { - appCaches = appCaches ?? AppCaches; + appCaches = appCaches ?? AppCaches.NoCache; var scopeAccessor = (IScopeAccessor) provider; var globalSettings = new GlobalSettings(); - var templateRepository = new TemplateRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger(), TestObjects.GetFileSystemsMock(), IOHelper, ShortStringHelper); - var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository, appCaches, ShortStringHelper); + var commonRepository = new ContentTypeCommonRepository(scopeAccessor, TemplateRepository, appCaches, ShortStringHelper); var languageRepository = new LanguageRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger(), Microsoft.Extensions.Options.Options.Create(globalSettings)); mediaTypeRepository = new MediaTypeRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger(), commonRepository, languageRepository, ShortStringHelper); var tagRepository = new TagRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger()); @@ -62,7 +70,7 @@ namespace Umbraco.Tests.Persistence.Repositories new DictionaryAppCache(), new IsolatedCaches(t => new ObjectCacheAppCache())); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider, out mediaTypeRepository, appCaches: realCache); @@ -71,10 +79,10 @@ namespace Umbraco.Tests.Persistence.Repositories udb.EnableSqlCount = false; - var mediaType = MockedContentTypes.CreateSimpleMediaType("umbTextpage1", "Textpage"); + var mediaType = MediaTypeBuilder.CreateSimpleMediaType("umbTextpage1", "Textpage"); mediaTypeRepository.Save(mediaType); - var media = MockedMedia.CreateSimpleMedia(mediaType, "hello", -1); + var media = MediaBuilder.CreateSimpleMedia(mediaType, "hello", -1); repository.Save(media); udb.EnableSqlCount = true; @@ -104,14 +112,14 @@ namespace Umbraco.Tests.Persistence.Repositories public void SaveMedia() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; var repository = CreateRepository(provider, out mediaTypeRepository); var mediaType = mediaTypeRepository.Get(1032); - var image = MockedMedia.CreateMediaImage(mediaType, -1); + var image = MediaBuilder.CreateMediaImage(mediaType, -1); // Act mediaTypeRepository.Save(mediaType); @@ -131,19 +139,19 @@ namespace Umbraco.Tests.Persistence.Repositories public void SaveMediaMultiple() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; var repository = CreateRepository(provider, out mediaTypeRepository); var mediaType = mediaTypeRepository.Get(1032); - var file = MockedMedia.CreateMediaFile(mediaType, -1); + var file = MediaBuilder.CreateMediaFile(mediaType, -1); // Act repository.Save(file); - var image = MockedMedia.CreateMediaImage(mediaType, -1); + var image = MediaBuilder.CreateMediaImage(mediaType, -1); repository.Save(image); // Assert @@ -160,14 +168,14 @@ namespace Umbraco.Tests.Persistence.Repositories public void GetMediaIsNotDirty() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; var repository = CreateRepository(provider, out mediaTypeRepository); // Act - var media = repository.Get(NodeDto.NodeIdSeed + 1); + var media = repository.Get(_testImage.Id); bool dirty = ((ICanBeDirty)media).IsDirty(); // Assert @@ -179,18 +187,18 @@ namespace Umbraco.Tests.Persistence.Repositories public void UpdateMedia() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; var repository = CreateRepository(provider, out mediaTypeRepository); // Act - var content = repository.Get(NodeDto.NodeIdSeed + 2); + var content = repository.Get(_testFile.Id); content.Name = "Test File Updated"; repository.Save(content); - var updatedContent = repository.Get(NodeDto.NodeIdSeed + 2); + var updatedContent = repository.Get(_testFile.Id); // Assert Assert.That(updatedContent.Id, Is.EqualTo(content.Id)); @@ -202,18 +210,18 @@ namespace Umbraco.Tests.Persistence.Repositories public void DeleteMedia() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; var repository = CreateRepository(provider, out mediaTypeRepository); // Act - var media = repository.Get(NodeDto.NodeIdSeed + 2); + var media = repository.Get(_testFile.Id); repository.Delete(media); - var deleted = repository.Get(NodeDto.NodeIdSeed + 2); - var exists = repository.Exists(NodeDto.NodeIdSeed + 2); + var deleted = repository.Get(_testFile.Id); + var exists = repository.Exists(_testFile.Id); // Assert Assert.That(deleted, Is.Null); @@ -225,17 +233,17 @@ namespace Umbraco.Tests.Persistence.Repositories public void GetMedia() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; var repository = CreateRepository(provider, out mediaTypeRepository); // Act - var media = repository.Get(NodeDto.NodeIdSeed + 1); + var media = repository.Get(_testImage.Id); // Assert - Assert.That(media.Id, Is.EqualTo(NodeDto.NodeIdSeed + 1)); + Assert.That(media.Id, Is.EqualTo(_testImage.Id)); Assert.That(media.CreateDate, Is.GreaterThan(DateTime.MinValue)); Assert.That(media.UpdateDate, Is.GreaterThan(DateTime.MinValue)); Assert.That(media.ParentId, Is.Not.EqualTo(0)); @@ -252,7 +260,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void QueryMedia() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; @@ -271,8 +279,8 @@ namespace Umbraco.Tests.Persistence.Repositories public void QueryMedia_ContentTypeIdFilter() { // Arrange - var folderMediaType = ServiceContext.MediaTypeService.Get(1031); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var folderMediaType = MediaTypeService.Get(1031); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider, out MediaTypeRepository mediaTypeRepository); @@ -280,7 +288,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Act for (int i = 0; i < 10; i++) { - var folder = MockedMedia.CreateMediaFolder(folderMediaType, -1); + var folder = MediaBuilder.CreateMediaFolder(folderMediaType, -1); repository.Save(folder); } @@ -302,8 +310,8 @@ namespace Umbraco.Tests.Persistence.Repositories // and we don't absolutely need it now, so leaving it out for now // Arrange - var folderMediaType = ServiceContext.MediaTypeService.Get(1031); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var folderMediaType = MediaTypeService.Get(1031); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider, out MediaTypeRepository mediaTypeRepository); @@ -311,7 +319,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Act for (int i = 0; i < 10; i++) { - var folder = MockedMedia.CreateMediaFolder(folderMediaType, -1); + var folder = MediaBuilder.CreateMediaFolder(folderMediaType, -1); repository.Save(folder); } @@ -329,7 +337,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void GetPagedResultsByQuery_FirstPage() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider, out MediaTypeRepository mediaTypeRepository); @@ -350,7 +358,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void GetPagedResultsByQuery_SecondPage() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; @@ -372,7 +380,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void GetPagedResultsByQuery_SinglePage() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; @@ -394,7 +402,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void GetPagedResultsByQuery_DescendingOrder() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; @@ -416,7 +424,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void GetPagedResultsByQuery_AlternateOrder() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; @@ -437,7 +445,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void GetPagedResultsByQuery_FilterMatchingSome() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; @@ -460,7 +468,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void GetPagedResultsByQuery_FilterMatchingAll() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider, out _); @@ -482,14 +490,14 @@ namespace Umbraco.Tests.Persistence.Repositories public void GetAllMediaByIds() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; var repository = CreateRepository(provider, out mediaTypeRepository); // Act - var medias = repository.GetMany(NodeDto.NodeIdSeed + 1, NodeDto.NodeIdSeed + 2); + var medias = repository.GetMany(_testImage.Id, _testFile.Id); // Assert Assert.That(medias, Is.Not.Null); @@ -502,7 +510,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void GetAllMedia() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; @@ -532,15 +540,15 @@ namespace Umbraco.Tests.Persistence.Repositories public void ExistMedia() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; var repository = CreateRepository(provider, out mediaTypeRepository); // Act - var exists = repository.Exists(NodeDto.NodeIdSeed + 1); - var existsToo = repository.Exists(NodeDto.NodeIdSeed + 1); + var exists = repository.Exists(_testImage.Id); + var existsToo = repository.Exists(_testImage.Id); var doesntExists = repository.Exists(NodeDto.NodeIdSeed + 5); // Assert @@ -554,7 +562,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void CountMedia() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { MediaTypeRepository mediaTypeRepository; @@ -570,28 +578,22 @@ namespace Umbraco.Tests.Persistence.Repositories } } - [TearDown] - public override void TearDown() - { - base.TearDown(); - } - public void CreateTestData() { - //Create and Save folder-Media -> (NodeDto.NodeIdSeed) - var folderMediaType = ServiceContext.MediaTypeService.Get(1031); - var folder = MockedMedia.CreateMediaFolder(folderMediaType, -1); - ServiceContext.MediaService.Save(folder, 0); + //Create and Save folder-Media -> (1051) + var folderMediaType = MediaTypeService.Get(1031); + _testFolder = MediaBuilder.CreateMediaFolder(folderMediaType, -1); + MediaService.Save(_testFolder, 0); - //Create and Save image-Media -> (NodeDto.NodeIdSeed + 1) - var imageMediaType = ServiceContext.MediaTypeService.Get(1032); - var image = MockedMedia.CreateMediaImage(imageMediaType, folder.Id); - ServiceContext.MediaService.Save(image, 0); + //Create and Save image-Media -> (1052) + var imageMediaType = MediaTypeService.Get(1032); + _testImage = MediaBuilder.CreateMediaImage(imageMediaType, _testFolder.Id); + MediaService.Save(_testImage, 0); - //Create and Save file-Media -> (NodeDto.NodeIdSeed + 2) - var fileMediaType = ServiceContext.MediaTypeService.Get(1033); - var file = MockedMedia.CreateMediaFile(fileMediaType, folder.Id); - ServiceContext.MediaService.Save(file, 0); + //Create and Save file-Media -> (1053) + var fileMediaType = MediaTypeService.Get(1033); + _testFile = MediaBuilder.CreateMediaFile(fileMediaType, _testFolder.Id); + MediaService.Save(_testFile, 0); } } } diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MediaTypeRepositoryTest.cs similarity index 80% rename from src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MediaTypeRepositoryTest.cs index b9b64bdd5d..77f18944c0 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MediaTypeRepositoryTest.cs @@ -4,30 +4,27 @@ using Microsoft.Extensions.Logging; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.Models; using Umbraco.Core.Models; using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.Dtos; +using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.Scoping; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Tests.Common.Builders; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class MediaTypeRepositoryTest : TestWithDatabaseBase + public class MediaTypeRepositoryTest : UmbracoIntegrationTest { + private IContentTypeCommonRepository CommonRepository => GetRequiredService(); + private ILanguageRepository LanguageRepository => GetRequiredService(); + private MediaTypeRepository CreateRepository(IScopeProvider provider) { - var cacheHelper = AppCaches.Disabled; - var globalSettings = new GlobalSettings(); - var templateRepository = new TemplateRepository((IScopeAccessor)provider, cacheHelper, LoggerFactory.CreateLogger(), TestObjects.GetFileSystemsMock(), IOHelper, ShortStringHelper); - var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, templateRepository, AppCaches, ShortStringHelper); - var languageRepository = new LanguageRepository((IScopeAccessor)provider, AppCaches, LoggerFactory.CreateLogger(), Microsoft.Extensions.Options.Options.Create(globalSettings)); - return new MediaTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, LoggerFactory.CreateLogger(), commonRepository, languageRepository, ShortStringHelper); + return new MediaTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, LoggerFactory.CreateLogger(), CommonRepository, LanguageRepository, ShortStringHelper); } private EntityContainerRepository CreateContainerRepository(IScopeProvider provider) @@ -39,7 +36,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Move() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var containerRepository = CreateContainerRepository(provider); @@ -53,7 +50,7 @@ namespace Umbraco.Tests.Persistence.Repositories containerRepository.Save(container2); - var contentType = (IMediaType)MockedContentTypes.CreateVideoMediaType(); + var contentType = (IMediaType)MediaTypeBuilder.CreateVideoMediaType(); contentType.ParentId = container2.Id; repository.Save(contentType); @@ -86,7 +83,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_Container() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var containerRepository = CreateContainerRepository(provider); @@ -104,7 +101,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Delete_Container() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var containerRepository = CreateContainerRepository(provider); @@ -126,7 +123,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_Container_Containing_Media_Types() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var containerRepository = CreateContainerRepository(provider); @@ -136,7 +133,7 @@ namespace Umbraco.Tests.Persistence.Repositories containerRepository.Save(container); - var contentType = MockedContentTypes.CreateVideoMediaType(); + var contentType = MediaTypeBuilder.CreateVideoMediaType(); contentType.ParentId = container.Id; repository.Save(contentType); @@ -148,7 +145,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Delete_Container_Containing_Media_Types() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var containerRepository = CreateContainerRepository(provider); @@ -158,7 +155,7 @@ namespace Umbraco.Tests.Persistence.Repositories containerRepository.Save(container); - IMediaType contentType = MockedContentTypes.CreateVideoMediaType(); + IMediaType contentType = MediaTypeBuilder.CreateVideoMediaType(); contentType.ParentId = container.Id; repository.Save(contentType); @@ -180,13 +177,13 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_MediaTypeRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); // Act - var contentType = MockedContentTypes.CreateVideoMediaType(); + var contentType = MediaTypeBuilder.CreateVideoMediaType(); repository.Save(contentType); @@ -208,17 +205,17 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_MediaTypeRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - var videoMediaType = MockedContentTypes.CreateVideoMediaType(); + var videoMediaType = MediaTypeBuilder.CreateVideoMediaType(); repository.Save(videoMediaType); // Act - var mediaType = repository.Get(NodeDto.NodeIdSeed); + var mediaType = repository.Get(videoMediaType.Id); mediaType.Thumbnail = "Doc2.png"; mediaType.PropertyGroups["Media"].PropertyTypes.Add(new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "subtitle") @@ -246,13 +243,13 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_MediaTypeRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); // Act - var mediaType = MockedContentTypes.CreateVideoMediaType(); + var mediaType = MediaTypeBuilder.CreateVideoMediaType(); repository.Save(mediaType); @@ -271,7 +268,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_MediaTypeRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); @@ -290,7 +287,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_By_Guid_On_MediaTypeRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); @@ -311,7 +308,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_MediaTypeRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); @@ -333,7 +330,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_By_Guid_On_MediaTypeRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); @@ -359,7 +356,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_MediaTypeRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); @@ -376,22 +373,22 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Update_MediaType_With_PropertyType_Removed() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - var mediaType = MockedContentTypes.CreateVideoMediaType(); + var mediaType = MediaTypeBuilder.CreateVideoMediaType(); repository.Save(mediaType); // Act - var mediaTypeV2 = repository.Get(NodeDto.NodeIdSeed); + var mediaTypeV2 = repository.Get(mediaType.Id); mediaTypeV2.PropertyGroups["Media"].PropertyTypes.Remove("title"); repository.Save(mediaTypeV2); - var mediaTypeV3 = repository.Get(NodeDto.NodeIdSeed); + var mediaTypeV3 = repository.Get(mediaType.Id); // Assert Assert.That(mediaTypeV3.PropertyTypes.Any(x => x.Alias == "title"), Is.False); @@ -404,17 +401,17 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_PropertyTypes_On_Video_MediaType() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - var mediaType = MockedContentTypes.CreateVideoMediaType(); + var mediaType = MediaTypeBuilder.CreateVideoMediaType(); repository.Save(mediaType); // Act - var contentType = repository.Get(NodeDto.NodeIdSeed); + var contentType = repository.Get(mediaType.Id); // Assert Assert.That(contentType.PropertyTypes.Count(), Is.EqualTo(2)); @@ -426,7 +423,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Verify_PropertyTypes_On_File_MediaType() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); @@ -439,11 +436,5 @@ namespace Umbraco.Tests.Persistence.Repositories Assert.That(contentType.PropertyGroups.Count(), Is.EqualTo(1)); } } - - [TearDown] - public override void TearDown() - { - base.TearDown(); - } } } diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MemberRepositoryTest.cs similarity index 67% rename from src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MemberRepositoryTest.cs index 04bf37c8d8..fa7ae66047 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MemberRepositoryTest.cs @@ -7,7 +7,6 @@ using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.Models; using Umbraco.Core.Models; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; @@ -16,44 +15,42 @@ using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Scoping; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Core.Security; +using Umbraco.Core.Services; +using Umbraco.Tests.Common.Builders; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class MemberRepositoryTest : TestWithDatabaseBase + public class MemberRepositoryTest : UmbracoIntegrationTest { - private MemberRepository CreateRepository(IScopeProvider provider, out MemberTypeRepository memberTypeRepository, out MemberGroupRepository memberGroupRepository) + private IPasswordHasher PasswordHasher => GetRequiredService(); + private IDataTypeService DataTypeService => GetRequiredService(); + private IMemberTypeRepository MemberTypeRepository => GetRequiredService(); + private IMemberGroupRepository MemberGroupRepository => GetRequiredService(); + + private MemberRepository CreateRepository(IScopeProvider provider) { var accessor = (IScopeAccessor) provider; - var globalSettings = new GlobalSettings(); - var templateRepository = Mock.Of(); - var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches, ShortStringHelper); - var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), Microsoft.Extensions.Options.Options.Create(globalSettings)); - memberTypeRepository = new MemberTypeRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), commonRepository, languageRepository, ShortStringHelper); - memberGroupRepository = new MemberGroupRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger()); - var tagRepo = new TagRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger()); - var relationTypeRepository = new RelationTypeRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger()); - var entityRepository = new EntityRepository(accessor); - var relationRepository = new RelationRepository(accessor, LoggerFactory.CreateLogger(), relationTypeRepository, entityRepository); + var tagRepo = GetRequiredService(); + var relationTypeRepository = GetRequiredService(); + var relationRepository = GetRequiredService(); var propertyEditors = new Lazy(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty()))); var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty()); - var repository = new MemberRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of(), relationRepository, relationTypeRepository, PasswordHasher, propertyEditors, dataValueReferences, DataTypeService); + var repository = new MemberRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), MemberTypeRepository, MemberGroupRepository, tagRepo, Mock.Of(), relationRepository, relationTypeRepository, PasswordHasher, propertyEditors, dataValueReferences, DataTypeService); return repository; } [Test] public void GetMember() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - MemberTypeRepository memberTypeRepository; - MemberGroupRepository memberGroupRepository; - var repository = CreateRepository(provider, out memberTypeRepository, out memberGroupRepository); + var repository = CreateRepository(provider); var member = CreateTestMember(); @@ -67,12 +64,10 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void GetMembers() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - MemberTypeRepository memberTypeRepository; - MemberGroupRepository memberGroupRepository; - var repository = CreateRepository(provider, out memberTypeRepository, out memberGroupRepository); + var repository = CreateRepository(provider); var type = CreateTestMemberType(); var m1 = CreateTestMember(type, "Test 1", "test1@test.com", "pass1", "test1"); @@ -90,12 +85,10 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void GetAllMembers() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - MemberTypeRepository memberTypeRepository; - MemberGroupRepository memberGroupRepository; - var repository = CreateRepository(provider, out memberTypeRepository, out memberGroupRepository); + var repository = CreateRepository(provider); var type = CreateTestMemberType(); for (var i = 0; i < 5; i++) @@ -116,12 +109,10 @@ namespace Umbraco.Tests.Persistence.Repositories public void QueryMember() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - MemberTypeRepository memberTypeRepository; - MemberGroupRepository memberGroupRepository; - var repository = CreateRepository(provider, out memberTypeRepository, out memberGroupRepository); + var repository = CreateRepository(provider); var key = Guid.NewGuid(); var member = CreateTestMember(key: key); @@ -139,12 +130,10 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void SaveMember() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - MemberTypeRepository memberTypeRepository; - MemberGroupRepository memberGroupRepository; - var repository = CreateRepository(provider, out memberTypeRepository, out memberGroupRepository); + var repository = CreateRepository(provider); var member = CreateTestMember(); @@ -164,17 +153,15 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void MemberHasBuiltinProperties() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - MemberTypeRepository memberTypeRepository; - MemberGroupRepository memberGroupRepository; - var repository = CreateRepository(provider, out memberTypeRepository, out memberGroupRepository); + var repository = CreateRepository(provider); - var memberType = MockedContentTypes.CreateSimpleMemberType(); - memberTypeRepository.Save(memberType); + var memberType = MemberTypeBuilder.CreateSimpleMemberType(); + MemberTypeRepository.Save(memberType); - var member = MockedMember.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty"); + var member = MemberBuilder.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty"); repository.Save(member); var sut = repository.Get(member.Id); @@ -196,18 +183,16 @@ namespace Umbraco.Tests.Persistence.Repositories public void SavingPreservesPassword() { IMember sut; - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - MemberTypeRepository memberTypeRepository; - MemberGroupRepository memberGroupRepository; - var repository = CreateRepository(provider, out memberTypeRepository, out memberGroupRepository); + var repository = CreateRepository(provider); - var memberType = MockedContentTypes.CreateSimpleMemberType(); - memberTypeRepository.Save(memberType); + var memberType = MemberTypeBuilder.CreateSimpleMemberType(); + MemberTypeRepository.Save(memberType); - var member = MockedMember.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty"); + var member = MemberBuilder.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty"); repository.Save(member); @@ -226,18 +211,16 @@ namespace Umbraco.Tests.Persistence.Repositories public void SavingUpdatesNameAndEmail() { IMember sut; - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - MemberTypeRepository memberTypeRepository; - MemberGroupRepository memberGroupRepository; - var repository = CreateRepository(provider, out memberTypeRepository, out memberGroupRepository); + var repository = CreateRepository(provider); - var memberType = MockedContentTypes.CreateSimpleMemberType(); - memberTypeRepository.Save(memberType); + var memberType = MemberTypeBuilder.CreateSimpleMemberType(); + MemberTypeRepository.Save(memberType); - var member = MockedMember.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty"); + var member = MemberBuilder.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty"); repository.Save(member); @@ -256,7 +239,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void QueryMember_WithSubQuery() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; var query = provider.SqlContext.Query().Where(x => ((Member) x).LongStringPropertyValue.Contains("1095") && @@ -276,21 +259,19 @@ namespace Umbraco.Tests.Persistence.Repositories private IMember CreateTestMember(IMemberType memberType = null, string name = null, string email = null, string password = null, string username = null, Guid? key = null) { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - MemberTypeRepository memberTypeRepository; - MemberGroupRepository memberGroupRepository; - var repository = CreateRepository(provider, out memberTypeRepository, out memberGroupRepository); + var repository = CreateRepository(provider); if (memberType == null) { - memberType = MockedContentTypes.CreateSimpleMemberType(); - memberTypeRepository.Save(memberType); + memberType = MemberTypeBuilder.CreateSimpleMemberType(); + MemberTypeRepository.Save(memberType); } - var member = MockedMember.CreateSimpleMember(memberType, name ?? "Johnny Hefty", email ?? "johnny@example.com", password ?? "123", username ?? "hefty", key); + var member = MemberBuilder.CreateSimpleMember(memberType, name ?? "Johnny Hefty", email ?? "johnny@example.com", password ?? "123", username ?? "hefty", key); repository.Save(member); scope.Complete(); @@ -300,15 +281,13 @@ namespace Umbraco.Tests.Persistence.Repositories private IMemberType CreateTestMemberType(string alias = null) { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - MemberTypeRepository memberTypeRepository; - MemberGroupRepository memberGroupRepository; - var repository = CreateRepository(provider, out memberTypeRepository, out memberGroupRepository); + var repository = CreateRepository(provider); - var memberType = MockedContentTypes.CreateSimpleMemberType(alias); - memberTypeRepository.Save(memberType); + var memberType = MemberTypeBuilder.CreateSimpleMemberType(alias); + MemberTypeRepository.Save(memberType); scope.Complete(); return memberType; } @@ -316,7 +295,7 @@ namespace Umbraco.Tests.Persistence.Repositories private Sql GetBaseQuery(bool isCount) { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; if (isCount) { var sqlCount = provider.SqlContext.Sql() @@ -356,7 +335,7 @@ namespace Umbraco.Tests.Persistence.Repositories private Sql GetSubquery() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; var sql = provider.SqlContext.Sql(); sql.Select("umbracoNode.id") .From() diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MemberTypeRepositoryTest.cs similarity index 79% rename from src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MemberTypeRepositoryTest.cs index 0a89c2dbe7..f2bf72a74d 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MemberTypeRepositoryTest.cs @@ -5,40 +5,37 @@ using Microsoft.Extensions.Logging; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.Models; using Umbraco.Core.Models; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.Scoping; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Tests.Common.Builders; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class MemberTypeRepositoryTest : TestWithDatabaseBase + public class MemberTypeRepositoryTest : UmbracoIntegrationTest { private MemberTypeRepository CreateRepository(IScopeProvider provider) { - var templateRepository = Mock.Of(); - var globalSettings = new GlobalSettings(); - var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, templateRepository, AppCaches, ShortStringHelper); - var languageRepository = new LanguageRepository((IScopeAccessor)provider, AppCaches.Disabled, Mock.Of>(), Microsoft.Extensions.Options.Options.Create(globalSettings)); + var commonRepository = GetRequiredService(); + var languageRepository = GetRequiredService(); return new MemberTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Mock.Of>(), commonRepository, languageRepository, ShortStringHelper); } [Test] public void Can_Persist_Member_Type() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - var memberType = (IMemberType) MockedContentTypes.CreateSimpleMemberType(); + var memberType = (IMemberType) MemberTypeBuilder.CreateSimpleMemberType(); repository.Save(memberType); var sut = repository.Get(memberType.Id); @@ -59,12 +56,12 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Persist_Member_Type_Same_Property_Keys() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - var memberType = (IMemberType)MockedContentTypes.CreateSimpleMemberType(); + var memberType = (IMemberType)MemberTypeBuilder.CreateSimpleMemberType(); repository.Save(memberType); scope.Complete(); @@ -85,12 +82,12 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Cannot_Persist_Member_Type_Without_Alias() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - var memberType = MockedContentTypes.CreateSimpleMemberType(); + var memberType = MemberTypeBuilder.CreateSimpleMemberType(); memberType.Alias = null; @@ -101,16 +98,16 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_All_Member_Types() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - var memberType1 = MockedContentTypes.CreateSimpleMemberType(); + var memberType1 = MemberTypeBuilder.CreateSimpleMemberType(); repository.Save(memberType1); - var memberType2 = MockedContentTypes.CreateSimpleMemberType(); + var memberType2 = MemberTypeBuilder.CreateSimpleMemberType(); memberType2.Name = "AnotherType"; memberType2.Alias = "anotherType"; repository.Save(memberType2); @@ -126,16 +123,16 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_All_Member_Types_By_Guid_Ids() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - var memberType1 = MockedContentTypes.CreateSimpleMemberType(); + var memberType1 = MemberTypeBuilder.CreateSimpleMemberType(); repository.Save(memberType1); - var memberType2 = MockedContentTypes.CreateSimpleMemberType(); + var memberType2 = MemberTypeBuilder.CreateSimpleMemberType(); memberType2.Name = "AnotherType"; memberType2.Alias = "anotherType"; repository.Save(memberType2); @@ -151,16 +148,16 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Member_Types_By_Guid_Id() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - var memberType1 = MockedContentTypes.CreateSimpleMemberType(); + var memberType1 = MemberTypeBuilder.CreateSimpleMemberType(); repository.Save(memberType1); - var memberType2 = MockedContentTypes.CreateSimpleMemberType(); + var memberType2 = MemberTypeBuilder.CreateSimpleMemberType(); memberType2.Name = "AnotherType"; memberType2.Alias = "anotherType"; repository.Save(memberType2); @@ -178,17 +175,17 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_All_Members_When_No_Properties_Assigned() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - var memberType1 = MockedContentTypes.CreateSimpleMemberType(); + var memberType1 = MemberTypeBuilder.CreateSimpleMemberType(); memberType1.PropertyTypeCollection.Clear(); repository.Save(memberType1); - var memberType2 = MockedContentTypes.CreateSimpleMemberType(); + var memberType2 = MemberTypeBuilder.CreateSimpleMemberType(); memberType2.PropertyTypeCollection.Clear(); memberType2.Name = "AnotherType"; memberType2.Alias = "anotherType"; @@ -205,12 +202,12 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Member_Type_By_Id() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + IMemberType memberType = MemberTypeBuilder.CreateSimpleMemberType(); repository.Save(memberType); memberType = repository.Get(memberType.Id); @@ -221,12 +218,12 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Member_Type_By_Guid_Id() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + IMemberType memberType = MemberTypeBuilder.CreateSimpleMemberType(); repository.Save(memberType); memberType = repository.Get(memberType.Key); @@ -240,12 +237,12 @@ namespace Umbraco.Tests.Persistence.Repositories { var stubs = ConventionsHelper.GetStandardPropertyTypeStubs(ShortStringHelper); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (provider.CreateScope()) { var repository = CreateRepository(provider); - IMemberType memberType = MockedContentTypes.CreateSimpleMemberType("mtype"); + IMemberType memberType = MemberTypeBuilder.CreateSimpleMemberType("mtype"); // created without the stub properties Assert.AreEqual(1, memberType.PropertyGroups.Count); @@ -285,12 +282,12 @@ namespace Umbraco.Tests.Persistence.Repositories { var stubs = ConventionsHelper.GetStandardPropertyTypeStubs(ShortStringHelper); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (provider.CreateScope()) { var repository = CreateRepository(provider); - IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + IMemberType memberType = MemberTypeBuilder.CreateSimpleMemberType(); // created without the stub properties Assert.AreEqual(1, memberType.PropertyGroups.Count); @@ -316,12 +313,12 @@ namespace Umbraco.Tests.Persistence.Repositories { var stubs = ConventionsHelper.GetStandardPropertyTypeStubs(ShortStringHelper); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (provider.CreateScope()) { var repository = CreateRepository(provider); - IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + IMemberType memberType = MemberTypeBuilder.CreateSimpleMemberType(); // created without the stub properties Assert.AreEqual(1, memberType.PropertyGroups.Count); @@ -350,13 +347,13 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Built_In_Member_Type_Properties_Are_Not_Reused_For_Different_Member_Types() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); - IMemberType memberType1 = MockedContentTypes.CreateSimpleMemberType(); - IMemberType memberType2 = MockedContentTypes.CreateSimpleMemberType("test2"); + IMemberType memberType1 = MemberTypeBuilder.CreateSimpleMemberType(); + IMemberType memberType2 = MemberTypeBuilder.CreateSimpleMemberType("test2"); repository.Save(memberType1); repository.Save(memberType2); @@ -372,13 +369,13 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Delete_MemberType() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = CreateRepository(provider); // Act - IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + IMemberType memberType = MemberTypeBuilder.CreateSimpleMemberType(); repository.Save(memberType); diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/NotificationsRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/NotificationsRepositoryTest.cs similarity index 98% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/NotificationsRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/NotificationsRepositoryTest.cs index 2735f869c0..f784390ced 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/NotificationsRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/NotificationsRepositoryTest.cs @@ -12,7 +12,7 @@ using Umbraco.Core.Scoping; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests/Persistence/Repositories/PartialViewRepositoryTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/PartialViewRepositoryTests.cs similarity index 86% rename from src/Umbraco.Tests/Persistence/Repositories/PartialViewRepositoryTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/PartialViewRepositoryTests.cs index 3c1a003a15..78ebbeb165 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/PartialViewRepositoryTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/PartialViewRepositoryTests.cs @@ -1,37 +1,36 @@ -using System.Linq; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; using Umbraco.Core; -using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Models; -using Umbraco.Core.PropertyEditors; using Umbraco.Core.Persistence.Repositories.Implement; -using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; using System; +using Umbraco.Core.Hosting; +using Umbraco.Tests.Integration.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] - [UmbracoTest(WithApplication = true, Database = UmbracoTestOptions.Database.NewEmptyPerFixture)] - public class PartialViewRepositoryTests : TestWithDatabaseBase + [UmbracoTest(Database = UmbracoTestOptions.Database.None)] + public class PartialViewRepositoryTests : UmbracoIntegrationTest { + private IHostingEnvironment HostingEnvironment => GetRequiredService(); private IFileSystem _fileSystem; - public override void SetUp() + [SetUp] + public void SetUp() { - base.SetUp(); - _fileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, LoggerFactory.CreateLogger(), Constants.SystemDirectories.MvcViews + "/Partials/"); } - protected override void Compose() + [TearDown] + public void TearDownFiles() { - base.Compose(); - - Composition.RegisterUnique(f => new DataEditorCollection(Enumerable.Empty())); + //Delete all files + Purge((PhysicalFileSystem)_fileSystem, ""); + _fileSystem = null; } [Test] @@ -42,7 +41,7 @@ namespace Umbraco.Tests.Persistence.Repositories var fileSystems = Mock.Of(); Mock.Get(fileSystems).Setup(x => x.PartialViewsFileSystem).Returns(_fileSystem); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repository = new PartialViewRepository(fileSystems, IOHelper); @@ -101,15 +100,6 @@ namespace Umbraco.Tests.Persistence.Repositories } } - [TearDown] - public override void TearDown() - { - base.TearDown(); - - //Delete all files - Purge((PhysicalFileSystem)_fileSystem, ""); - _fileSystem = null; - } private void Purge(PhysicalFileSystem fs, string path) { diff --git a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/PublicAccessRepositoryTest.cs similarity index 76% rename from src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/PublicAccessRepositoryTest.cs index d2f606c973..a02889c6ae 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/PublicAccessRepositoryTest.cs @@ -4,28 +4,36 @@ using System.Linq; using Microsoft.Extensions.Logging; using NUnit.Framework; using Umbraco.Core.Configuration.Models; +using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Scoping; +using Umbraco.Core.Services; +using Umbraco.Tests.Common.Builders; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.Testing; using Content = Umbraco.Core.Models.Content; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class PublicAccessRepositoryTest : TestWithDatabaseBase + public class PublicAccessRepositoryTest : UmbracoIntegrationTest { + private IContentTypeRepository ContentTypeRepository => GetRequiredService(); + private DocumentRepository DocumentRepository => (DocumentRepository) GetRequiredService(); + [Test] public void Can_Delete() { var content = CreateTestData(3).ToArray(); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repo = new PublicAccessRepository((IScopeAccessor) provider, AppCaches, LoggerFactory.CreateLogger()); @@ -54,7 +62,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var content = CreateTestData(3).ToArray(); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { scope.Database.AsUmbracoDatabase().EnableSqlTrace = true; @@ -94,7 +102,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var content = CreateTestData(3).ToArray(); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { scope.Database.AsUmbracoDatabase().EnableSqlTrace = true; @@ -125,13 +133,10 @@ namespace Umbraco.Tests.Persistence.Repositories Assert.IsTrue(found[0].HasIdentity); Assert.AreNotEqual(default(DateTime), found[0].CreateDate); Assert.AreNotEqual(default(DateTime), found[0].UpdateDate); - Assert.AreEqual(2, found[0].Rules.Count()); - Assert.AreEqual("test", found[0].Rules.First().RuleValue); - Assert.AreEqual("RoleName", found[0].Rules.First().RuleType); + CollectionAssert.AreEquivalent(found[0].Rules, entry.Rules); Assert.AreNotEqual(default(DateTime), found[0].Rules.First().CreateDate); Assert.AreNotEqual(default(DateTime), found[0].Rules.First().UpdateDate); Assert.IsTrue(found[0].Rules.First().HasIdentity); - Assert.AreEqual("test2", found[0].Rules.Skip(1).First().RuleValue); } } @@ -140,7 +145,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var content = CreateTestData(3).ToArray(); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repo = new PublicAccessRepository((IScopeAccessor) provider, AppCaches, LoggerFactory.CreateLogger()); @@ -178,7 +183,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var content = CreateTestData(3).ToArray(); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repo = new PublicAccessRepository((IScopeAccessor) provider, AppCaches, LoggerFactory.CreateLogger()); @@ -206,7 +211,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var content = CreateTestData(30).ToArray(); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repo = new PublicAccessRepository((IScopeAccessor) provider, AppCaches, LoggerFactory.CreateLogger()); @@ -270,7 +275,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var content = CreateTestData(3).ToArray(); - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { var repo = new PublicAccessRepository((IScopeAccessor) provider, AppCaches, LoggerFactory.CreateLogger()); @@ -302,41 +307,19 @@ namespace Umbraco.Tests.Persistence.Repositories } } - - private DocumentRepository CreateRepository(IScopeProvider provider, out ContentTypeRepository contentTypeRepository) - { - var accessor = (IScopeAccessor) provider; - var globalSettings = new GlobalSettings(); - var templateRepository = new TemplateRepository(accessor, AppCaches, LoggerFactory.CreateLogger(), TestObjects.GetFileSystemsMock(), IOHelper, ShortStringHelper); - var tagRepository = new TagRepository(accessor, AppCaches, LoggerFactory.CreateLogger()); - var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches, ShortStringHelper); - var languageRepository = new LanguageRepository(accessor, AppCaches, LoggerFactory.CreateLogger(), Microsoft.Extensions.Options.Options.Create(globalSettings)); - contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, LoggerFactory.CreateLogger(), commonRepository, languageRepository, ShortStringHelper); - var relationTypeRepository = new RelationTypeRepository(accessor, AppCaches, LoggerFactory.CreateLogger()); - var entityRepository = new EntityRepository(accessor); - var relationRepository = new RelationRepository(accessor, LoggerFactory.CreateLogger(), relationTypeRepository, entityRepository); - var propertyEditors = new Lazy(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty()))); - var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty()); - var repository = new DocumentRepository(accessor, AppCaches, LoggerFactory.CreateLogger(), LoggerFactory, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences, DataTypeService); - return repository; - } - private IEnumerable CreateTestData(int count) { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { - ContentTypeRepository ctRepo; - var repo = CreateRepository(provider, out ctRepo); - - var ct = MockedContentTypes.CreateBasicContentType("testing"); - ctRepo.Save(ct); + var ct = ContentTypeBuilder.CreateBasicContentType("testing"); + ContentTypeRepository.Save(ct); var result = new List(); for (int i = 0; i < count; i++) { var c = new Content("test" + i, -1, ct); - repo.Save(c); + DocumentRepository.Save(c); result.Add(c); } scope.Complete(); diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/RedirectUrlRepositoryTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RedirectUrlRepositoryTests.cs similarity index 98% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/RedirectUrlRepositoryTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RedirectUrlRepositoryTests.cs index ea1a7ed8db..8ae792b92f 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/RedirectUrlRepositoryTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RedirectUrlRepositoryTests.cs @@ -11,7 +11,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/RelationRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationRepositoryTest.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/RelationRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationRepositoryTest.cs index 63e4ada345..1989478186 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/RelationRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationRepositoryTest.cs @@ -19,7 +19,7 @@ using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/RelationTypeRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationTypeRepositoryTest.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/RelationTypeRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationTypeRepositoryTest.cs index 6a93d73713..8d436eeeed 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/RelationTypeRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationTypeRepositoryTest.cs @@ -9,7 +9,7 @@ using Umbraco.Core.Scoping; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests/Persistence/Repositories/ScriptRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ScriptRepositoryTest.cs similarity index 89% rename from src/Umbraco.Tests/Persistence/Repositories/ScriptRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ScriptRepositoryTest.cs index 0a9632b9ad..435ccaa322 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ScriptRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ScriptRepositoryTest.cs @@ -5,33 +5,29 @@ using System.Text; using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Composing; -using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Models; -using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; -using Umbraco.Core.PropertyEditors; -using Umbraco.Tests.Common.Builders; -using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] - [UmbracoTest(WithApplication = true, Database = UmbracoTestOptions.Database.NewEmptyPerFixture)] - public class ScriptRepositoryTest : TestWithDatabaseBase + [UmbracoTest(Database = UmbracoTestOptions.Database.None)] + public class ScriptRepositoryTest : UmbracoIntegrationTest { + private IHostingEnvironment HostingEnvironment => GetRequiredService(); + private IFileSystems _fileSystems; private IFileSystem _fileSystem; - public override void SetUp() + [SetUp] + public void SetUpFileSystem() { - base.SetUp(); - _fileSystems = Mock.Of(); _fileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, LoggerFactory.CreateLogger(), new GlobalSettings().UmbracoScriptsPath); Mock.Get(_fileSystems).Setup(x => x.ScriptsFileSystem).Returns(_fileSystem); @@ -41,24 +37,25 @@ namespace Umbraco.Tests.Persistence.Repositories } } + [TearDown] + public void TearDownFileSystem() + { + //Delete all files + Purge(_fileSystems.ScriptsFileSystem, ""); + _fileSystems = null; + } + private IScriptRepository CreateRepository() { var globalSettings = new GlobalSettings(); return new ScriptRepository(_fileSystems, IOHelper, Microsoft.Extensions.Options.Options.Create(globalSettings)); } - protected override void Compose() - { - base.Compose(); - - Composition.RegisterUnique(f => new DataEditorCollection(Enumerable.Empty())); - } - [Test] public void Can_Instantiate_Repository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = ScopeProvider.CreateScope()) { // Act @@ -73,7 +70,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Add_On_ScriptRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = ScopeProvider.CreateScope()) { var repository = CreateRepository(); @@ -92,7 +89,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_ScriptRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = ScopeProvider.CreateScope()) { var repository = CreateRepository(); @@ -118,7 +115,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Delete_On_ScriptRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = ScopeProvider.CreateScope()) { var repository = CreateRepository(); @@ -138,7 +135,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Get_On_ScriptRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = ScopeProvider.CreateScope()) { var repository = CreateRepository(); @@ -157,7 +154,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_On_ScriptRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = ScopeProvider.CreateScope()) { var repository = CreateRepository(); @@ -185,7 +182,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_GetAll_With_Params_On_ScriptRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = ScopeProvider.CreateScope()) { var repository = CreateRepository(); @@ -213,7 +210,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Exists_On_ScriptRepository() { // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = ScopeProvider.CreateScope()) { var repository = CreateRepository(); @@ -232,7 +229,7 @@ namespace Umbraco.Tests.Persistence.Repositories const string content = "/// "; // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = ScopeProvider.CreateScope()) { var repository = CreateRepository(); @@ -265,7 +262,7 @@ namespace Umbraco.Tests.Persistence.Repositories { // unless noted otherwise, no changes / 7.2.8 - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = ScopeProvider.CreateScope()) { var repository = CreateRepository(); @@ -335,16 +332,6 @@ namespace Umbraco.Tests.Persistence.Repositories } } - [TearDown] - public override void TearDown() - { - base.TearDown(); - - //Delete all files - Purge(_fileSystems.ScriptsFileSystem, ""); - _fileSystems = null; - } - private void Purge(IFileSystem fs, string path) { var files = fs.GetFiles(path, "*.js"); diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/ServerRegistrationRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ServerRegistrationRepositoryTest.cs similarity index 98% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/ServerRegistrationRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ServerRegistrationRepositoryTest.cs index 3107770672..e5304e1e31 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/ServerRegistrationRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ServerRegistrationRepositoryTest.cs @@ -10,7 +10,7 @@ using Umbraco.Core.Scoping; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/SimilarNodeNameTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/SimilarNodeNameTests.cs new file mode 100644 index 0000000000..747bb542cd --- /dev/null +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/SimilarNodeNameTests.cs @@ -0,0 +1,228 @@ +using System.Linq; +using NUnit.Framework; +using Umbraco.Core.Persistence.Repositories.Implement; + +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories +{ + [TestFixture] + public class SimilarNodeNameTests + { + public void Name_Is_Suffixed() + { + var names = new[] + { + new SimilarNodeName { Id = 1, Name = "Zulu" } + }; + + var res = SimilarNodeName.GetUniqueName(names, 0, "Zulu"); + Assert.AreEqual("Zulu (1)", res); + } + + [Test] + public void Suffixed_Name_Is_Incremented() + { + var names = new[] + { + new SimilarNodeName { Id = 1, Name = "Zulu" }, + new SimilarNodeName { Id = 2, Name = "Kilo (1)" }, + new SimilarNodeName { Id = 3, Name = "Kilo" }, + }; + + var res = SimilarNodeName.GetUniqueName(names, 0, "Kilo (1)"); + Assert.AreEqual("Kilo (2)", res); + } + + [Test] + public void Lower_Number_Suffix_Is_Inserted() + { + var names = new[] + { + new SimilarNodeName { Id = 1, Name = "Golf" }, + new SimilarNodeName { Id = 2, Name = "Golf (2)" }, + }; + + var res = SimilarNodeName.GetUniqueName(names, 0, "Golf"); + Assert.AreEqual("Golf (1)", res); + } + + [Test] + [TestCase(0, "Alpha", "Alpha (3)")] + [TestCase(0, "alpha", "alpha (3)")] + public void Case_Is_Ignored(int nodeId, string nodeName, string expected) + { + var names = new[] + { + new SimilarNodeName { Id = 1, Name = "Alpha" }, + new SimilarNodeName { Id = 2, Name = "Alpha (1)" }, + new SimilarNodeName { Id = 3, Name = "Alpha (2)" }, + }; + var res = SimilarNodeName.GetUniqueName(names, nodeId, nodeName); + + Assert.AreEqual(expected, res); + } + + [Test] + public void Empty_List_Causes_Unchanged_Name() + { + var names = new SimilarNodeName[] { }; + + var res = SimilarNodeName.GetUniqueName(names, 0, "Charlie"); + + Assert.AreEqual("Charlie", res); + } + + [Test] + [TestCase(0, "", " (1)")] + [TestCase(0, null, " (1)")] + public void Empty_Name_Is_Suffixed(int nodeId, string nodeName, string expected) + { + var names = new SimilarNodeName[] { }; + + var res = SimilarNodeName.GetUniqueName(names, nodeId, nodeName); + + Assert.AreEqual(expected, res); + } + + [Test] + public void Matching_NoedId_Causes_No_Change() + { + var names = new[] + { + new SimilarNodeName { Id = 1, Name = "Kilo (1)" }, + new SimilarNodeName { Id = 2, Name = "Yankee" }, + new SimilarNodeName { Id = 3, Name = "Kilo" }, + }; + + var res = SimilarNodeName.GetUniqueName(names, 1, "Kilo (1)"); + + Assert.AreEqual("Kilo (1)", res); + } + + [Test] + public void Extra_MultiSuffixed_Name_Is_Ignored() + { + // Sequesnce is: Test, Test (1), Test (2) + // Ignore: Test (1) (1) + var names = new[] + { + new SimilarNodeName { Id = 1, Name = "Alpha (2)" }, + new SimilarNodeName { Id = 2, Name = "Test" }, + new SimilarNodeName { Id = 3, Name = "Test (1)" }, + new SimilarNodeName { Id = 4, Name = "Test (2)" }, + new SimilarNodeName { Id = 5, Name = "Test (1) (1)" }, + }; + + var res = SimilarNodeName.GetUniqueName(names, 0, "Test"); + + Assert.AreEqual("Test (3)", res); + } + + [Test] + public void Matched_Name_Is_Suffixed() + { + var names = new[] + { + new SimilarNodeName { Id = 1, Name = "Test" }, + }; + + var res = SimilarNodeName.GetUniqueName(names, 0, "Test"); + + Assert.AreEqual("Test (1)", res); + } + + [Test] + public void MultiSuffixed_Name_Is_Icremented() + { + // "Test (1)" is treated as the "original" version of the name. + // "Test (1) (1)" is the suffixed result of a copy, and therefore is incremented + // Hence this test result should be the same as Suffixed_Name_Is_Incremented + var names = new[] + { + new SimilarNodeName { Id = 1, Name = "Test (1)" }, + new SimilarNodeName { Id = 2, Name = "Test (1) (1)" }, + }; + + var res = SimilarNodeName.GetUniqueName(names, 0, "Test (1) (1)"); + + Assert.AreEqual("Test (1) (2)", res); + } + + [Test] + public void Suffixed_Name_Causes_Secondary_Suffix() + { + var names = new[] + { + new SimilarNodeName { Id = 6, Name = "Alpha (1)" } + }; + var res = SimilarNodeName.GetUniqueName(names, 0, "Alpha (1)"); + + Assert.AreEqual("Alpha (1) (1)", res); + } + + + [TestCase("Test (0)", "Test (0) (1)")] + [TestCase("Test (-1)", "Test (-1) (1)")] + [TestCase("Test (1) (-1)", "Test (1) (-1) (1)")] + public void NonPositive_Suffix_Is_Ignored(string suffix, string expected) + { + var names = new[] + { + new SimilarNodeName { Id = 6, Name = suffix } + }; + var res = SimilarNodeName.GetUniqueName(names, 0, suffix); + + Assert.AreEqual(expected, res); + } + + + + /* Original Tests - Can be deleted, as new tests cover all cases */ + + [TestCase(0, "Charlie", "Charlie")] + [TestCase(0, "Zulu", "Zulu (1)")] + [TestCase(0, "Golf", "Golf (1)")] + [TestCase(0, "Kilo", "Kilo (2)")] + [TestCase(0, "Alpha", "Alpha (3)")] + //[TestCase(0, "Kilo (1)", "Kilo (1) (1)")] // though... we might consider "Kilo (2)" + [TestCase(0, "Kilo (1)", "Kilo (2)")] // names[] contains "Kilo" AND "Kilo (1)", which implies that result should be "Kilo (2)" + [TestCase(6, "Kilo (1)", "Kilo (1)")] // because of the id + [TestCase(0, "alpha", "alpha (3)")] + [TestCase(0, "", " (1)")] + [TestCase(0, null, " (1)")] + public void Test(int nodeId, string nodeName, string expected) + { + var names = new[] + { + new SimilarNodeName { Id = 1, Name = "Alpha (2)" }, + new SimilarNodeName { Id = 2, Name = "Alpha" }, + new SimilarNodeName { Id = 3, Name = "Golf" }, + new SimilarNodeName { Id = 4, Name = "Zulu" }, + new SimilarNodeName { Id = 5, Name = "Mike" }, + new SimilarNodeName { Id = 6, Name = "Kilo (1)" }, + new SimilarNodeName { Id = 7, Name = "Yankee" }, + new SimilarNodeName { Id = 8, Name = "Kilo" }, + new SimilarNodeName { Id = 9, Name = "Golf (2)" }, + new SimilarNodeName { Id = 10, Name = "Alpha (1)" }, + }; + + Assert.AreEqual(expected, SimilarNodeName.GetUniqueName(names, nodeId, nodeName)); + } + + [Test] + [Explicit("This test fails! We need to fix up the logic")] + public void TestMany() + { + var names = new[] + { + new SimilarNodeName { Id = 1, Name = "Alpha (2)" }, + new SimilarNodeName { Id = 2, Name = "Test" }, + new SimilarNodeName { Id = 3, Name = "Test (1)" }, + new SimilarNodeName { Id = 4, Name = "Test (2)" }, + new SimilarNodeName { Id = 22, Name = "Test (1) (1)" }, + }; + + //fixme - this will yield "Test (2)" which is already in use + Assert.AreEqual("Test (3)", SimilarNodeName.GetUniqueName(names, 0, "Test")); + } + } +} diff --git a/src/Umbraco.Tests/Persistence/Repositories/StylesheetRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/StylesheetRepositoryTest.cs similarity index 95% rename from src/Umbraco.Tests/Persistence/Repositories/StylesheetRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/StylesheetRepositoryTest.cs index 2ba2e7679e..58f3d7ad95 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/StylesheetRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/StylesheetRepositoryTest.cs @@ -6,31 +6,31 @@ using System.Text; using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Composing; -using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Models; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; -using Umbraco.Tests.Common.Builders; -using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.Integration.Implementations; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] - [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)] - public class StylesheetRepositoryTest : TestWithDatabaseBase + [UmbracoTest(Database = UmbracoTestOptions.Database.None)] + public class StylesheetRepositoryTest : UmbracoIntegrationTest { private IFileSystems _fileSystems; private IFileSystem _fileSystem; - public override void SetUp() - { - base.SetUp(); + private IIOHelper IOHelper => GetRequiredService(); + private IHostingEnvironment HostingEnvironment => GetRequiredService(); + [SetUp] + public void SetUpFileSystem() + { _fileSystems = Mock.Of(); _fileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, LoggerFactory.CreateLogger(), new GlobalSettings().UmbracoCssPath); Mock.Get(_fileSystems).Setup(x => x.StylesheetsFileSystem).Returns(_fileSystem); @@ -38,6 +38,14 @@ namespace Umbraco.Tests.Persistence.Repositories _fileSystem.AddFile("styles.css", stream); } + [TearDown] + public void TearDownFileSystem() + { + //Delete all files + Purge((PhysicalFileSystem) _fileSystem, ""); + _fileSystem = null; + } + private IStylesheetRepository CreateRepository() { var globalSettings = new GlobalSettings(); @@ -317,16 +325,6 @@ namespace Umbraco.Tests.Persistence.Repositories } } - [TearDown] - public override void TearDown() - { - base.TearDown(); - - //Delete all files - Purge((PhysicalFileSystem) _fileSystem, ""); - _fileSystem = null; - } - private void Purge(PhysicalFileSystem fs, string path) { var files = fs.GetFiles(path, "*.css"); diff --git a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TagRepositoryTest.cs similarity index 60% rename from src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TagRepositoryTest.cs index 5037541fae..47164a0ee0 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TagRepositoryTest.cs @@ -1,29 +1,32 @@ -using System; -using System.Linq; +using System.Linq; using Microsoft.Extensions.Logging; -using Moq; using NUnit.Framework; using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.Models; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; -using Umbraco.Core.PropertyEditors; using Umbraco.Core.Scoping; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Core.Services; +using Umbraco.Tests.Common.Builders; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class TagRepositoryTest : TestWithDatabaseBase + public class TagRepositoryTest : UmbracoIntegrationTest { + private IFileService FileService => GetRequiredService(); + private IContentTypeRepository ContentTypeRepository => GetRequiredService(); + private IDocumentRepository DocumentRepository => GetRequiredService(); + private IMediaRepository MediaRepository => GetRequiredService(); + private IMediaTypeRepository MediaTypeRepository => GetRequiredService(); + [Test] public void Can_Perform_Add_On_Repository() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { var repository = CreateRepository(provider); @@ -43,7 +46,7 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Perform_Multiple_Adds_On_Repository() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { var repository = CreateRepository(provider); @@ -73,18 +76,19 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Create_Tag_Relations() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - // create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content); var repository = CreateRepository(provider); repository.Assign( @@ -103,18 +107,19 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Append_Tag_Relations() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content); var repository = CreateRepository(provider); repository.Assign( @@ -142,18 +147,19 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Replace_Tag_Relations() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content); var repository = CreateRepository(provider); repository.Assign( @@ -184,18 +190,19 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Merge_Tag_Relations() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content); var repository = CreateRepository(provider); repository.Assign( @@ -224,18 +231,19 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Clear_Tag_Relations() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content); var repository = CreateRepository(provider); repository.Assign( @@ -260,18 +268,19 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Remove_Specific_Tags_From_Property() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content); var repository = CreateRepository(provider); repository.Assign( @@ -304,20 +313,21 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Content_By_Id() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); - var content2 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content2); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); + var content2 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content2); var repository = CreateRepository(provider); repository.Assign( @@ -348,20 +358,21 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Content_By_Key() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); - var content2 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content2); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); + var content2 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content2); var repository = CreateRepository(provider); repository.Assign( @@ -393,20 +404,21 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_All() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); - var content2 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content2); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); + var content2 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content2); var repository = CreateRepository(provider); repository.Assign( @@ -428,20 +440,21 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_All_With_Ids() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); - var content2 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content2); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); + var content2 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content2); var repository = CreateRepository(provider); var tags = new[] @@ -468,20 +481,21 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Content_For_Group() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); - var content2 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content2); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); + var content2 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content2); var repository = CreateRepository(provider); repository.Assign( @@ -512,18 +526,19 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Property_By_Id() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); var repository = CreateRepository(provider); repository.Assign( @@ -556,18 +571,19 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Property_By_Key() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); var repository = CreateRepository(provider); repository.Assign( @@ -600,18 +616,19 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Property_For_Group() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); var repository = CreateRepository(provider); repository.Assign( @@ -645,25 +662,25 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Entity_Type() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - var mediaRepository = CreateMediaRepository(provider, out var mediaTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); - var mediaType = MockedContentTypes.CreateImageMediaType("image2"); - mediaTypeRepository.Save(mediaType); + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); - var media1 = MockedMedia.CreateMediaImage(mediaType, -1); - mediaRepository.Save(media1); + var mediaType = MediaTypeBuilder.CreateImageMediaType("image2"); + MediaTypeRepository.Save(mediaType); + + var media1 = MediaBuilder.CreateMediaImage(mediaType, -1); + MediaRepository.Save(media1); var repository = CreateRepository(provider); repository.Assign( @@ -702,25 +719,25 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tags_For_Entity_Type_For_Group() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - var mediaRepository = CreateMediaRepository(provider, out var mediaTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); - var mediaType = MockedContentTypes.CreateImageMediaType("image2"); - mediaTypeRepository.Save(mediaType); + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); - var media1 = MockedMedia.CreateMediaImage(mediaType, -1); - mediaRepository.Save(media1); + var mediaType = MediaTypeBuilder.CreateImageMediaType("image2"); + MediaTypeRepository.Save(mediaType); + + var media1 = MediaBuilder.CreateMediaImage(mediaType, -1); + MediaRepository.Save(media1); var repository = CreateRepository(provider); repository.Assign( @@ -754,18 +771,19 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Cascade_Deletes_Tag_Relations() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); + + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); var repository = CreateRepository(provider); repository.Assign( @@ -779,7 +797,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag4", Group = "test"} }, false); - contentRepository.Delete(content1); + DocumentRepository.Delete(content1); Assert.AreEqual(0, scope.Database.ExecuteScalar( "SELECT COUNT(*) FROM cmsTagRelationship WHERE nodeId=@nodeId AND propertyTypeId=@propTypeId", @@ -790,28 +808,28 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tagged_Entities_For_Tag_Group() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - var mediaRepository = CreateMediaRepository(provider, out var mediaTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); - var content2 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content2); + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); - var mediaType = MockedContentTypes.CreateImageMediaType("image2"); - mediaTypeRepository.Save(mediaType); + var content2 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content2); - var media1 = MockedMedia.CreateMediaImage(mediaType, -1); - mediaRepository.Save(media1); + var mediaType = MediaTypeBuilder.CreateImageMediaType("image2"); + MediaTypeRepository.Save(mediaType); + + var media1 = MediaBuilder.CreateMediaImage(mediaType, -1); + MediaRepository.Save(media1); var repository = CreateRepository(provider); repository.Assign( @@ -870,31 +888,31 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Get_Tagged_Entities_For_Tag() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (ScopeProvider.CreateScope()) { - var contentRepository = CreateDocumentRepository(provider, out var contentTypeRepository); - var mediaRepository = CreateMediaRepository(provider, out var mediaTypeRepository); - //create data to relate to - var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); - ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! - contentTypeRepository.Save(contentType); + // We have to create and save a template, otherwise we get an FK violation on contentType. + var template = TemplateBuilder.CreateTextPageTemplate(); + FileService.SaveTemplate(template); + + var contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); + ContentTypeRepository.Save(contentType); - var content1 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content1); + var content1 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content1); - var content2 = MockedContent.CreateSimpleContent(contentType); - contentRepository.Save(content2); + var content2 = ContentBuilder.CreateSimpleContent(contentType); + DocumentRepository.Save(content2); - var mediaType = MockedContentTypes.CreateImageMediaType("image2"); - mediaTypeRepository.Save(mediaType); + var mediaType = MediaTypeBuilder.CreateImageMediaType("image2"); + MediaTypeRepository.Save(mediaType); - var media1 = MockedMedia.CreateMediaImage(mediaType, -1); - mediaRepository.Save(media1); + var media1 = MediaBuilder.CreateMediaImage(mediaType, -1); + MediaRepository.Save(media1); var repository = CreateRepository(provider); @@ -951,42 +969,5 @@ namespace Umbraco.Tests.Persistence.Repositories { return new TagRepository((IScopeAccessor) provider, AppCaches.Disabled, LoggerFactory.CreateLogger()); } - - private DocumentRepository CreateDocumentRepository(IScopeProvider provider, out ContentTypeRepository contentTypeRepository) - { - var accessor = (IScopeAccessor) provider; - var globalSettings = new GlobalSettings(); - var templateRepository = new TemplateRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), TestObjects.GetFileSystemsMock(), IOHelper, ShortStringHelper); - var tagRepository = new TagRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger()); - var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches.Disabled, ShortStringHelper); - var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), Microsoft.Extensions.Options.Options.Create(globalSettings)); - contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), commonRepository, languageRepository, ShortStringHelper); - var relationTypeRepository = new RelationTypeRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger()); - var entityRepository = new EntityRepository(accessor); - var relationRepository = new RelationRepository(accessor, LoggerFactory.CreateLogger(), relationTypeRepository, entityRepository); - var propertyEditors = new Lazy(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty()))); - var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty()); - var repository = new DocumentRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), LoggerFactory, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences, DataTypeService); - return repository; - } - - private MediaRepository CreateMediaRepository(IScopeProvider provider, out MediaTypeRepository mediaTypeRepository) - { - var accessor = (IScopeAccessor) provider; - var globalSettings = new GlobalSettings(); - var templateRepository = new TemplateRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), TestObjects.GetFileSystemsMock(), IOHelper, ShortStringHelper); - var tagRepository = new TagRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger()); - var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches.Disabled, ShortStringHelper); - var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), Microsoft.Extensions.Options.Options.Create(globalSettings)); - mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), commonRepository, languageRepository, ShortStringHelper); - var relationTypeRepository = new RelationTypeRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger()); - var entityRepository = new EntityRepository(accessor); - var relationRepository = new RelationRepository(accessor, LoggerFactory.CreateLogger(), relationTypeRepository, entityRepository); - var propertyEditors = new Lazy(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty()))); - var mediaUrlGenerators = new MediaUrlGeneratorCollection(Enumerable.Empty()); - var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty()); - var repository = new MediaRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), LoggerFactory, mediaTypeRepository, tagRepository, Mock.Of(), relationRepository, relationTypeRepository, propertyEditors, mediaUrlGenerators, dataValueReferences, DataTypeService); - return repository; - } } } diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/TemplateRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TemplateRepositoryTest.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/TemplateRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TemplateRepositoryTest.cs index a7894b9dc6..3452ab22ae 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/TemplateRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TemplateRepositoryTest.cs @@ -21,7 +21,7 @@ using Umbraco.Tests.Integration.Implementations; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/UserGroupRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/UserGroupRepositoryTest.cs similarity index 97% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/UserGroupRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/UserGroupRepositoryTest.cs index f6444fef00..e67b9f9b60 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/UserGroupRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/UserGroupRepositoryTest.cs @@ -9,7 +9,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] @@ -17,7 +17,7 @@ namespace Umbraco.Tests.Integration.Persistence.Repositories { private UserGroupRepository CreateRepository(IScopeProvider provider) { - return new UserGroupRepository((IScopeAccessor) provider, Core.Cache.AppCaches.Disabled, LoggerFactory.CreateLogger(), LoggerFactory, ShortStringHelper); + return new UserGroupRepository((IScopeAccessor) provider, global::Umbraco.Core.Cache.AppCaches.Disabled, LoggerFactory.CreateLogger(), LoggerFactory, ShortStringHelper); } [Test] @@ -128,7 +128,7 @@ namespace Umbraco.Tests.Integration.Persistence.Repositories var id = userGroup.Id; - var repository2 = new UserGroupRepository((IScopeAccessor) provider, Core.Cache.AppCaches.Disabled, LoggerFactory.CreateLogger(), LoggerFactory, ShortStringHelper); + var repository2 = new UserGroupRepository((IScopeAccessor) provider, global::Umbraco.Core.Cache.AppCaches.Disabled, LoggerFactory.CreateLogger(), LoggerFactory, ShortStringHelper); repository2.Delete(userGroup); scope.Complete(); diff --git a/src/Umbraco.Tests.Integration/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/UserRepositoryTest.cs similarity index 74% rename from src/Umbraco.Tests.Integration/Persistence/Repositories/UserRepositoryTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/UserRepositoryTest.cs index 0df619544d..ba773716fd 100644 --- a/src/Umbraco.Tests.Integration/Persistence/Repositories/UserRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/UserRepositoryTest.cs @@ -9,21 +9,28 @@ using Umbraco.Core.Cache; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.Scoping; using Umbraco.Core.Serialization; +using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Repositories +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, WithApplication = true, Logger = UmbracoTestOptions.Logger.Console)] public class UserRepositoryTest : UmbracoIntegrationTest { + private IDocumentRepository DocumentRepository => GetRequiredService(); + private IContentTypeRepository ContentTypeRepository => GetRequiredService(); + private IMediaTypeRepository MediaTypeRepository => GetRequiredService(); + private IMediaRepository MediaRepository => GetRequiredService(); + private UserRepository CreateRepository(IScopeProvider provider) { var accessor = (IScopeAccessor) provider; @@ -349,6 +356,98 @@ namespace Umbraco.Tests.Persistence.Repositories } } + [Test] + public void Validate_Login_Session() + { + // Arrange + var provider = ScopeProvider; + var user = UserBuilder.CreateUser(); + using (var scope = provider.CreateScope(autoComplete: true)) + { + var repository = CreateRepository(provider); + repository.Save(user); + } + + using (var scope = provider.CreateScope(autoComplete: true)) + { + var repository = CreateRepository(provider); + var sessionId = repository.CreateLoginSession(user.Id, "1.2.3.4"); + + // manually update this record to be in the past + scope.Database.Execute(scope.SqlContext.Sql() + .Update(u => u.Set(x => x.LoggedOutUtc, DateTime.UtcNow.AddDays(-100))) + .Where(x => x.SessionId == sessionId)); + + var isValid = repository.ValidateLoginSession(user.Id, sessionId); + Assert.IsFalse(isValid); + + // create a new one + sessionId = repository.CreateLoginSession(user.Id, "1.2.3.4"); + isValid = repository.ValidateLoginSession(user.Id, sessionId); + Assert.IsTrue(isValid); + } + } + + [Test] + public void Can_Perform_Update_On_UserRepository() + { + var ct = ContentTypeBuilder.CreateBasicContentType("test"); + var mt = MediaTypeBuilder.CreateSimpleMediaType("testmedia", "TestMedia"); + + // Arrange + var provider = ScopeProvider; + using (var scope = provider.CreateScope(autoComplete: true)) + { + var userRepository = CreateRepository(provider); + var userGroupRepository = CreateUserGroupRepository(provider); + + ContentTypeRepository.Save(ct); + MediaTypeRepository.Save(mt); + + var content = ContentBuilder.CreateBasicContent(ct); + var media = MediaBuilder.CreateSimpleMedia(mt, "asdf", -1); + + DocumentRepository.Save(content); + MediaRepository.Save(media); + + var user = CreateAndCommitUserWithGroup(userRepository, userGroupRepository); + + // Act + var resolved = (User) userRepository.Get(user.Id); + + resolved.Name = "New Name"; + //the db column is not used, default permissions are taken from the user type's permissions, this is a getter only + //resolved.DefaultPermissions = "ZYX"; + resolved.Language = "fr"; + resolved.IsApproved = false; + resolved.RawPasswordValue = "new"; + resolved.IsLockedOut = true; + resolved.StartContentIds = new[] { content.Id }; + resolved.StartMediaIds = new[] { media.Id }; + resolved.Email = "new@new.com"; + resolved.Username = "newName"; + + userRepository.Save(resolved); + + var updatedItem = (User) userRepository.Get(user.Id); + + // Assert + Assert.That(updatedItem.Id, Is.EqualTo(resolved.Id)); + Assert.That(updatedItem.Name, Is.EqualTo(resolved.Name)); + Assert.That(updatedItem.Language, Is.EqualTo(resolved.Language)); + Assert.That(updatedItem.IsApproved, Is.EqualTo(resolved.IsApproved)); + Assert.That(updatedItem.RawPasswordValue, Is.EqualTo(resolved.RawPasswordValue)); + Assert.That(updatedItem.IsLockedOut, Is.EqualTo(resolved.IsLockedOut)); + Assert.IsTrue(updatedItem.StartContentIds.UnsortedSequenceEqual(resolved.StartContentIds)); + Assert.IsTrue(updatedItem.StartMediaIds.UnsortedSequenceEqual(resolved.StartMediaIds)); + Assert.That(updatedItem.Email, Is.EqualTo(resolved.Email)); + Assert.That(updatedItem.Username, Is.EqualTo(resolved.Username)); + Assert.That(updatedItem.AllowedSections.Count(), Is.EqualTo(resolved.AllowedSections.Count())); + foreach (var allowedSection in resolved.AllowedSections) + Assert.IsTrue(updatedItem.AllowedSections.Contains(allowedSection)); + } + } + private void AssertPropertyValues(IUser updatedItem, IUser originalUser) { Assert.That(updatedItem.Id, Is.EqualTo(originalUser.Id)); diff --git a/src/Umbraco.Tests/Persistence/UnitOfWorkTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/UnitOfWorkTests.cs similarity index 76% rename from src/Umbraco.Tests/Persistence/UnitOfWorkTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/UnitOfWorkTests.cs index 68c11e221d..f6197e0193 100644 --- a/src/Umbraco.Tests/Persistence/UnitOfWorkTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/UnitOfWorkTests.cs @@ -1,19 +1,19 @@ using System; using NUnit.Framework; using Umbraco.Core; -using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class UnitOfWorkTests : TestWithDatabaseBase + public class UnitOfWorkTests : UmbracoIntegrationTest { [Test] public void ReadLockNonExisting() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; Assert.Throws(() => { using (var scope = provider.CreateScope()) @@ -27,7 +27,7 @@ namespace Umbraco.Tests.Persistence [Test] public void ReadLockExisting() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { scope.ReadLock(Constants.Locks.Servers); @@ -38,7 +38,7 @@ namespace Umbraco.Tests.Persistence [Test] public void WriteLockNonExisting() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; Assert.Throws(() => { using (var scope = provider.CreateScope()) @@ -52,7 +52,7 @@ namespace Umbraco.Tests.Persistence [Test] public void WriteLockExisting() { - var provider = TestObjects.GetScopeProvider(LoggerFactory); + var provider = ScopeProvider; using (var scope = provider.CreateScope()) { scope.WriteLock(Constants.Locks.Servers); diff --git a/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopeFileSystemsTests.cs similarity index 62% rename from src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopeFileSystemsTests.cs index 8c98bc99ff..38a3674d21 100644 --- a/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopeFileSystemsTests.cs @@ -2,94 +2,110 @@ using System.IO; using System.Text; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Moq; using NUnit.Framework; using Umbraco.Core; -using Umbraco.Web.Composing; +using Umbraco.Core.Configuration.Models; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; -using Umbraco.Tests.TestHelpers; +using Umbraco.Core.Scoping; using Umbraco.Tests.Testing; -using Umbraco.Core.Composing.CompositionExtensions; +using Umbraco.Tests.Integration.Testing; using FileSystems = Umbraco.Core.IO.FileSystems; namespace Umbraco.Tests.Scoping { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewEmptyPerTest)] - public class ScopeFileSystemsTests : TestWithDatabaseBase + public class ScopeFileSystemsTests : UmbracoIntegrationTest { - public override void SetUp() - { - base.SetUp(); + private IMediaFileSystem MediaFileSystem => GetRequiredService(); + private IHostingEnvironment HostingEnvironment => GetRequiredService(); + [SetUp] + public void SetUp() + { SafeCallContext.Clear(); ClearFiles(IOHelper); } - protected override void ComposeApplication(bool withApplication) + [TearDown] + public void Teardown() { - base.ComposeApplication(withApplication); - - if (!withApplication) return; - - // re-register with actual media fs - Composition.ComposeFileSystems(); - } - - public override void TearDown() - { - base.TearDown(); SafeCallContext.Clear(); FileSystems.ResetShadowId(); ClearFiles(IOHelper); } - private static void ClearFiles(IIOHelper ioHelper) + private void ClearFiles(IIOHelper ioHelper) { TestHelper.DeleteDirectory(ioHelper.MapPath("media")); TestHelper.DeleteDirectory(ioHelper.MapPath("FileSysTests")); TestHelper.DeleteDirectory(ioHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs")); } - - [TestCase(true)] - [TestCase(false)] - public void CreateMediaTest(bool complete) + + [Test] + public void test_MediaFileSystem_does_not_write_to_physical_file_system_when_scoped_if_scope_does_not_complete() { - var physMediaFileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, Mock.Of>(), IOHelper.MapPath("media"), "ignore"); - var mediaFileSystem = Current.MediaFileSystem; + var rootPath = HostingEnvironment.MapPathWebRoot(GlobalSettings.UmbracoMediaPath); + var rootUrl = HostingEnvironment.ToAbsolute(GlobalSettings.UmbracoMediaPath); + var physMediaFileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, GetRequiredService>(), rootPath, rootUrl); + var mediaFileSystem = MediaFileSystem; Assert.IsFalse(physMediaFileSystem.FileExists("f1.txt")); - var scopeProvider = ScopeProvider; - using (var scope = scopeProvider.CreateScope(scopeFileSystems: true)) + using (ScopeProvider.CreateScope(scopeFileSystems: true)) { using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) mediaFileSystem.AddFile("f1.txt", ms); Assert.IsTrue(mediaFileSystem.FileExists("f1.txt")); Assert.IsFalse(physMediaFileSystem.FileExists("f1.txt")); - if (complete) - scope.Complete(); + Assert.IsTrue(mediaFileSystem.FileExists("f1.txt")); Assert.IsFalse(physMediaFileSystem.FileExists("f1.txt")); } - if (complete) + // After scope is disposed ensure shadow wrapper didn't commit to physical + Assert.IsFalse(MediaFileSystem.FileExists("f1.txt")); + Assert.IsFalse(physMediaFileSystem.FileExists("f1.txt")); + } + + [Test] + public void test_MediaFileSystem_writes_to_physical_file_system_when_scoped_and_scope_is_completed() + { + var rootPath = HostingEnvironment.MapPathWebRoot(GlobalSettings.UmbracoMediaPath); + var rootUrl = HostingEnvironment.ToAbsolute(GlobalSettings.UmbracoMediaPath); + var physMediaFileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, GetRequiredService>(), rootPath, rootUrl); + var mediaFileSystem = MediaFileSystem; + + Assert.IsFalse(physMediaFileSystem.FileExists("f1.txt")); + + using (var scope = ScopeProvider.CreateScope(scopeFileSystems: true)) { - Assert.IsTrue(Current.MediaFileSystem.FileExists("f1.txt")); - Assert.IsTrue(physMediaFileSystem.FileExists("f1.txt")); - } - else - { - Assert.IsFalse(Current.MediaFileSystem.FileExists("f1.txt")); + using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) + mediaFileSystem.AddFile("f1.txt", ms); + Assert.IsTrue(mediaFileSystem.FileExists("f1.txt")); + Assert.IsFalse(physMediaFileSystem.FileExists("f1.txt")); + + scope.Complete(); + + Assert.IsTrue(mediaFileSystem.FileExists("f1.txt")); Assert.IsFalse(physMediaFileSystem.FileExists("f1.txt")); } + + // After scope is disposed ensure shadow wrapper writes to physical file system + Assert.IsTrue(MediaFileSystem.FileExists("f1.txt")); + Assert.IsTrue(physMediaFileSystem.FileExists("f1.txt")); } [Test] public void MultiThread() { - var physMediaFileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, Mock.Of>(),IOHelper.MapPath("media"), "ignore"); - var mediaFileSystem = Current.MediaFileSystem; + var rootPath = HostingEnvironment.MapPathWebRoot(GlobalSettings.UmbracoMediaPath); + var rootUrl = HostingEnvironment.ToAbsolute(GlobalSettings.UmbracoMediaPath); + var physMediaFileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, GetRequiredService>(), rootPath, rootUrl); + var mediaFileSystem = MediaFileSystem; var scopeProvider = ScopeProvider; using (var scope = scopeProvider.CreateScope(scopeFileSystems: true)) @@ -141,7 +157,7 @@ namespace Umbraco.Tests.Scoping [Test] public void SingleShadowEvenDetached() { - var scopeProvider = ScopeProvider; + var scopeProvider = (ScopeProvider)ScopeProvider; using (var scope = scopeProvider.CreateScope(scopeFileSystems: true)) { using (new SafeCallContext()) // not nesting! diff --git a/src/Umbraco.Tests.Integration/Services/AuditServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/AuditServiceTests.cs similarity index 98% rename from src/Umbraco.Tests.Integration/Services/AuditServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/AuditServiceTests.cs index 474229372c..d7385a7acf 100644 --- a/src/Umbraco.Tests.Integration/Services/AuditServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/AuditServiceTests.cs @@ -9,7 +9,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Services/CachedDataTypeServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/CachedDataTypeServiceTests.cs similarity index 96% rename from src/Umbraco.Tests.Integration/Services/CachedDataTypeServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/CachedDataTypeServiceTests.cs index a5b89dc2cf..89a3cdafb1 100644 --- a/src/Umbraco.Tests.Integration/Services/CachedDataTypeServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/CachedDataTypeServiceTests.cs @@ -6,7 +6,7 @@ using Umbraco.Core.Services; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { /// /// Tests covering the DataTypeService with cache enabled diff --git a/src/Umbraco.Tests.Integration/Services/ConsentServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ConsentServiceTests.cs similarity index 98% rename from src/Umbraco.Tests.Integration/Services/ConsentServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ConsentServiceTests.cs index 3cc8666099..905697159d 100644 --- a/src/Umbraco.Tests.Integration/Services/ConsentServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ConsentServiceTests.cs @@ -6,7 +6,7 @@ using Umbraco.Core.Services; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)] diff --git a/src/Umbraco.Tests.Integration/Services/ContentEventsTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/ContentEventsTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs index 913ed6dd00..45b0eb0660 100644 --- a/src/Umbraco.Tests.Integration/Services/ContentEventsTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs @@ -15,7 +15,7 @@ using Umbraco.Tests.Testing; using Umbraco.Web; using Umbraco.Web.Cache; -namespace Umbraco.Tests.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Services/ContentServiceEventTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceEventTests.cs similarity index 98% rename from src/Umbraco.Tests.Integration/Services/ContentServiceEventTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceEventTests.cs index 9e71eabd3c..9e1f6a6c6c 100644 --- a/src/Umbraco.Tests.Integration/Services/ContentServiceEventTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceEventTests.cs @@ -11,7 +11,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, @@ -34,7 +34,7 @@ namespace Umbraco.Tests.Integration.Services ContentRepositoryBase.ThrowOnWarning = true; _globalSettings = new GlobalSettings(); // TODO: remove this once IPublishedSnapShotService has been implemented with nucache. - Core.Services.Implement.ContentTypeService.ClearScopeEvents(); + global::Umbraco.Core.Services.Implement.ContentTypeService.ClearScopeEvents(); CreateTestData(); } diff --git a/src/Umbraco.Tests.Integration/Services/ContentServicePerformanceTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServicePerformanceTest.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/ContentServicePerformanceTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServicePerformanceTest.cs index 273a24337a..0ac59e240c 100644 --- a/src/Umbraco.Tests.Integration/Services/ContentServicePerformanceTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServicePerformanceTest.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using NUnit.Framework; @@ -17,7 +16,7 @@ using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Services/ContentServicePublishBranchTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServicePublishBranchTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/ContentServicePublishBranchTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServicePublishBranchTests.cs index 54103af6f1..fccd708286 100644 --- a/src/Umbraco.Tests.Integration/Services/ContentServicePublishBranchTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServicePublishBranchTests.cs @@ -11,7 +11,7 @@ using Umbraco.Tests.Testing; // ReSharper disable CommentTypo // ReSharper disable StringLiteralTypo -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true, WithApplication = true)] diff --git a/src/Umbraco.Tests.Integration/Services/ContentServiceTagsTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceTagsTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/ContentServiceTagsTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceTagsTests.cs index 3cf02f6b10..6473b69d3c 100644 --- a/src/Umbraco.Tests.Integration/Services/ContentServiceTagsTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceTagsTests.cs @@ -11,7 +11,7 @@ using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, diff --git a/src/Umbraco.Tests.Integration/Services/ContentServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/ContentServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceTests.cs index c4ae836bec..36b5e91f34 100644 --- a/src/Umbraco.Tests.Integration/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceTests.cs @@ -3,21 +3,15 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; -using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.Models; using Umbraco.Core.Events; -using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Scoping; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; using Umbraco.Tests.Common.Builders; @@ -25,7 +19,7 @@ using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { /// /// Tests covering all methods in the ContentService class. diff --git a/src/Umbraco.Tests.Integration/Services/ContentTypeServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentTypeServiceTests.cs similarity index 96% rename from src/Umbraco.Tests.Integration/Services/ContentTypeServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentTypeServiceTests.cs index e7a3f9d066..e5234205c4 100644 --- a/src/Umbraco.Tests.Integration/Services/ContentTypeServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentTypeServiceTests.cs @@ -13,7 +13,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true)] @@ -358,13 +358,13 @@ namespace Umbraco.Tests.Integration.Services var global = ContentTypeBuilder.CreateSimpleContentType("global", "Global", defaultTemplateId: template.Id); ContentTypeService.Save(global); - var components = ContentTypeBuilder.CreateSimpleContentType("components", "Components", global, true, defaultTemplateId: template.Id); + var components = ContentTypeBuilder.CreateSimpleContentType("components", "Components", global, randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(components); - var component = ContentTypeBuilder.CreateSimpleContentType("component", "Component", components, true, defaultTemplateId: template.Id); + var component = ContentTypeBuilder.CreateSimpleContentType("component", "Component", components, randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(component); - var category = ContentTypeBuilder.CreateSimpleContentType("category", "Category", global, true, defaultTemplateId: template.Id); + var category = ContentTypeBuilder.CreateSimpleContentType("category", "Category", global, randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(category); var success = category.AddContentType(component); @@ -378,10 +378,10 @@ namespace Umbraco.Tests.Integration.Services var template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); - var contentType = ContentTypeBuilder.CreateSimpleContentType("page", "Page", null, true, defaultTemplateId: template.Id); + var contentType = ContentTypeBuilder.CreateSimpleContentType("page", "Page", randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(contentType); - var childContentType = ContentTypeBuilder.CreateSimpleContentType("childPage", "Child Page", contentType, true, "Child Content", defaultTemplateId: template.Id); + var childContentType = ContentTypeBuilder.CreateSimpleContentType("childPage", "Child Page", contentType, randomizeAliases: true, propertyGroupName: "Child Content", defaultTemplateId: template.Id); ContentTypeService.Save(childContentType); var content = ContentService.Create("Page 1", -1, childContentType.Alias); ContentService.Save(content); @@ -593,10 +593,10 @@ namespace Umbraco.Tests.Integration.Services var parentContentType1 = ContentTypeBuilder.CreateSimpleContentType("parent1", "Parent1", defaultTemplateId: template.Id); ContentTypeService.Save(parentContentType1); - var parentContentType2 = ContentTypeBuilder.CreateSimpleContentType("parent2", "Parent2", null, true, defaultTemplateId: template.Id); + var parentContentType2 = ContentTypeBuilder.CreateSimpleContentType("parent2", "Parent2", randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(parentContentType2); - var simpleContentType = ContentTypeBuilder.CreateSimpleContentType("category", "Category", parentContentType1, true, defaultTemplateId: template.Id) as IContentType; + var simpleContentType = ContentTypeBuilder.CreateSimpleContentType("category", "Category", parentContentType1, randomizeAliases: true, defaultTemplateId: template.Id) as IContentType; ContentTypeService.Save(simpleContentType); // Act @@ -690,10 +690,10 @@ namespace Umbraco.Tests.Integration.Services var parentContentType1 = ContentTypeBuilder.CreateSimpleContentType("parent1", "Parent1", defaultTemplateId: template.Id); ContentTypeService.Save(parentContentType1); - var parentContentType2 = ContentTypeBuilder.CreateSimpleContentType("parent2", "Parent2", null, true, defaultTemplateId: template.Id); + var parentContentType2 = ContentTypeBuilder.CreateSimpleContentType("parent2", "Parent2", randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(parentContentType2); - var simpleContentType = ContentTypeBuilder.CreateSimpleContentType("category", "Category", parentContentType1, true, defaultTemplateId: template.Id); + var simpleContentType = ContentTypeBuilder.CreateSimpleContentType("category", "Category", parentContentType1, randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(simpleContentType); // Act @@ -733,7 +733,7 @@ namespace Umbraco.Tests.Integration.Services var parent = ContentTypeBuilder.CreateSimpleContentType(defaultTemplateId: template.Id); ContentTypeService.Save(parent); - var child = ContentTypeBuilder.CreateSimpleContentType("simpleChildPage", "Simple Child Page", parent, true, defaultTemplateId: template.Id); + var child = ContentTypeBuilder.CreateSimpleContentType("simpleChildPage", "Simple Child Page", parent, randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(child); var composition = ContentTypeBuilder.CreateMetaContentType(); ContentTypeService.Save(composition); @@ -762,11 +762,11 @@ namespace Umbraco.Tests.Integration.Services var template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); - var basePage = ContentTypeBuilder.CreateSimpleContentType("basePage", "Base Page", null, true, defaultTemplateId: template.Id); + var basePage = ContentTypeBuilder.CreateSimpleContentType("basePage", "Base Page", randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(basePage); var contentPage = ContentTypeBuilder.CreateSimpleContentType("contentPage", "Content Page", basePage, defaultTemplateId: template.Id); ContentTypeService.Save(contentPage); - var advancedPage = ContentTypeBuilder.CreateSimpleContentType("advancedPage", "Advanced Page", contentPage, true, defaultTemplateId: template.Id); + var advancedPage = ContentTypeBuilder.CreateSimpleContentType("advancedPage", "Advanced Page", contentPage, randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(advancedPage); var metaComposition = ContentTypeBuilder.CreateMetaContentType(); @@ -1048,11 +1048,11 @@ namespace Umbraco.Tests.Integration.Services var template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); - var page = ContentTypeBuilder.CreateSimpleContentType("page", "Page", null, true, "Content", defaultTemplateId: template.Id); + var page = ContentTypeBuilder.CreateSimpleContentType("page", "Page", randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(page); - var contentPage = ContentTypeBuilder.CreateSimpleContentType("contentPage", "Content Page", page, true, "Content_", defaultTemplateId: template.Id); + var contentPage = ContentTypeBuilder.CreateSimpleContentType("contentPage", "Content Page", page, randomizeAliases: true, propertyGroupName: "Content_", defaultTemplateId: template.Id); ContentTypeService.Save(contentPage); - var advancedPage = ContentTypeBuilder.CreateSimpleContentType("advancedPage", "Advanced Page", contentPage, true, "Details", defaultTemplateId: template.Id); + var advancedPage = ContentTypeBuilder.CreateSimpleContentType("advancedPage", "Advanced Page", contentPage, randomizeAliases: true, propertyGroupName: "Details", defaultTemplateId: template.Id); ContentTypeService.Save(advancedPage); var contentMetaComposition = ContentTypeBuilder.CreateContentMetaContentType(); @@ -1157,11 +1157,11 @@ namespace Umbraco.Tests.Integration.Services // Arrange var template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); - var basePage = ContentTypeBuilder.CreateSimpleContentType("basePage", "Base Page", null, true, defaultTemplateId: template.Id); + var basePage = ContentTypeBuilder.CreateSimpleContentType("basePage", "Base Page", randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(basePage); - var contentPage = ContentTypeBuilder.CreateSimpleContentType("contentPage", "Content Page", basePage, true, defaultTemplateId: template.Id); + var contentPage = ContentTypeBuilder.CreateSimpleContentType("contentPage", "Content Page", basePage, randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(contentPage); - var advancedPage = ContentTypeBuilder.CreateSimpleContentType("advancedPage", "Advanced Page", contentPage, true, defaultTemplateId: template.Id); + var advancedPage = ContentTypeBuilder.CreateSimpleContentType("advancedPage", "Advanced Page", contentPage, randomizeAliases: true, defaultTemplateId: template.Id); ContentTypeService.Save(advancedPage); var metaComposition = ContentTypeBuilder.CreateMetaContentType(); @@ -1200,7 +1200,7 @@ namespace Umbraco.Tests.Integration.Services // create 'page' content type with a 'Content_' group var template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); - var page = ContentTypeBuilder.CreateSimpleContentType("page", "Page", null, false, "Content_", defaultTemplateId: template.Id); + var page = ContentTypeBuilder.CreateSimpleContentType("page", "Page", propertyGroupName: "Content_", defaultTemplateId: template.Id); Assert.AreEqual(1, page.PropertyGroups.Count); Assert.AreEqual("Content_", page.PropertyGroups.First().Name); Assert.AreEqual(3, page.PropertyTypes.Count()); @@ -1210,7 +1210,7 @@ namespace Umbraco.Tests.Integration.Services ContentTypeService.Save(page); // create 'contentPage' content type as a child of 'page' - var contentPage = ContentTypeBuilder.CreateSimpleContentType("contentPage", "Content Page", page, true, defaultTemplateId: template.Id); + var contentPage = ContentTypeBuilder.CreateSimpleContentType("contentPage", "Content Page", page, randomizeAliases: true, defaultTemplateId: template.Id); Assert.AreEqual(1, page.PropertyGroups.Count); Assert.AreEqual("Content_", page.PropertyGroups.First().Name); Assert.AreEqual(3, contentPage.PropertyTypes.Count()); @@ -1281,11 +1281,11 @@ namespace Umbraco.Tests.Integration.Services // Arrange var template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); - var page = ContentTypeBuilder.CreateSimpleContentType("page", "Page", null, true, "Content_", defaultTemplateId: template.Id); + var page = ContentTypeBuilder.CreateSimpleContentType("page", "Page", randomizeAliases: true, propertyGroupName: "Content_", defaultTemplateId: template.Id); ContentTypeService.Save(page); - var contentPage = ContentTypeBuilder.CreateSimpleContentType("contentPage", "Content Page", page, true, "Contentx", defaultTemplateId: template.Id); + var contentPage = ContentTypeBuilder.CreateSimpleContentType("contentPage", "Content Page", page, randomizeAliases: true, propertyGroupName: "Contentx", defaultTemplateId: template.Id); ContentTypeService.Save(contentPage); - var advancedPage = ContentTypeBuilder.CreateSimpleContentType("advancedPage", "Advanced Page", contentPage, true, "Contenty", defaultTemplateId: template.Id); + var advancedPage = ContentTypeBuilder.CreateSimpleContentType("advancedPage", "Advanced Page", contentPage, randomizeAliases: true, propertyGroupName: "Contenty", defaultTemplateId: template.Id); ContentTypeService.Save(advancedPage); var contentMetaComposition = ContentTypeBuilder.CreateContentMetaContentType(); @@ -1355,9 +1355,9 @@ namespace Umbraco.Tests.Integration.Services // Arrange var template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); - var page = ContentTypeBuilder.CreateSimpleContentType("page", "Page", null, true, "Content_", defaultTemplateId: template.Id); + var page = ContentTypeBuilder.CreateSimpleContentType("page", "Page", randomizeAliases: true, propertyGroupName: "Content_", defaultTemplateId: template.Id); ContentTypeService.Save(page); - var contentPage = ContentTypeBuilder.CreateSimpleContentType("contentPage", "Content Page", page, true, "Content", defaultTemplateId: template.Id); + var contentPage = ContentTypeBuilder.CreateSimpleContentType("contentPage", "Content Page", page, randomizeAliases: true, propertyGroupName: "Content", defaultTemplateId: template.Id); ContentTypeService.Save(contentPage); var contentMetaComposition = ContentTypeBuilder.CreateContentMetaContentType(); @@ -1589,11 +1589,11 @@ namespace Umbraco.Tests.Integration.Services typeA.PropertyTypes.First(x => x.Alias.InvariantEquals("title")).Variations = ContentVariation.Culture; // with a variant property ContentTypeService.Save(typeA); - var typeB = ContentTypeBuilder.CreateSimpleContentType("b", "B", typeA, true, defaultTemplateId: template.Id); + var typeB = ContentTypeBuilder.CreateSimpleContentType("b", "B", typeA, randomizeAliases: true, defaultTemplateId: template.Id); typeB.Variations = ContentVariation.Nothing; // make it invariant ContentTypeService.Save(typeB); - var typeC = ContentTypeBuilder.CreateSimpleContentType("c", "C", typeA, true, defaultTemplateId: template.Id); + var typeC = ContentTypeBuilder.CreateSimpleContentType("c", "C", typeA, randomizeAliases: true, defaultTemplateId: template.Id); typeC.Variations = ContentVariation.Culture; // make it variant ContentTypeService.Save(typeC); @@ -1705,7 +1705,7 @@ namespace Umbraco.Tests.Integration.Services { var contentType = ContentTypeBuilder.CreateSimpleContentType("childType" + i, "ChildType" + i, //make the last entry in the list, this one's parent - list.Last(), true, defaultTemplateId: template.Id); + list.Last(), randomizeAliases: true, defaultTemplateId: template.Id); list.Add(contentType); } diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentTypeServiceVariantsTests.cs similarity index 76% rename from src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentTypeServiceVariantsTests.cs index 30d68d92e0..d11210c093 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentTypeServiceVariantsTests.cs @@ -2,99 +2,31 @@ using System.Collections.Generic; using System.Linq; using System.Threading; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using Moq; using NUnit.Framework; -using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration.Models; -using Umbraco.Core.Hosting; using Umbraco.Core.Models; -using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Services; -using Umbraco.Core.Strings; using Umbraco.Core.Sync; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Tests.Common.Builders; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; using Umbraco.Web.PublishedCache; -using Umbraco.Web.PublishedCache.NuCache; -using Umbraco.Web.PublishedCache.NuCache.DataSource; -namespace Umbraco.Tests.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [Apartment(ApartmentState.STA)] - [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true, WithApplication = true)] - public class ContentTypeServiceVariantsTests : TestWithSomeContentBase + [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true)] + public class ContentTypeServiceVariantsTests : UmbracoIntegrationTest { - protected override void Compose() - { - base.Compose(); - - // pfew - see note in ScopedNuCacheTests? - Composition.RegisterUnique(); - Composition.RegisterUnique(f => Mock.Of()); - Composition.WithCollectionBuilder() - .Add(() => Composition.TypeLoader.GetCacheRefreshers()); - } - - protected override IPublishedSnapshotService CreatePublishedSnapshotService(GlobalSettings globalSettings = null) - { - var options = new PublishedSnapshotServiceOptions { IgnoreLocalDb = true }; - var publishedSnapshotAccessor = new UmbracoContextPublishedSnapshotAccessor(Umbraco.Web.Composing.Current.UmbracoContextAccessor); - var runtimeStateMock = new Mock(); - runtimeStateMock.Setup(x => x.Level).Returns(() => RuntimeLevel.Run); - - var contentTypeFactory = Factory.GetInstance(); - var documentRepository = Factory.GetInstance(); - var mediaRepository = Mock.Of(); - var memberRepository = Mock.Of(); - var hostingEnvironment = Mock.Of(); - - var typeFinder = TestHelper.GetTypeFinder(); - - var nuCacheSettings = new NuCacheSettings(); - - return new PublishedSnapshotService( - options, - null, - runtimeStateMock.Object, - ServiceContext, - contentTypeFactory, - publishedSnapshotAccessor, - Mock.Of(), - ProfilingLogger, - NullLoggerFactory.Instance, - ScopeProvider, - documentRepository, mediaRepository, memberRepository, - DefaultCultureAccessor, - new DatabaseDataSource(Mock.Of>()), - Microsoft.Extensions.Options.Options.Create(globalSettings ?? new GlobalSettings()), - Factory.GetInstance(), - Mock.Of(), - new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider(ShortStringHelper) }), - hostingEnvironment, - Mock.Of(), - IOHelper, - Microsoft.Extensions.Options.Options.Create(nuCacheSettings)); - } - - public class LocalServerMessenger : ServerMessengerBase - { - public LocalServerMessenger() - : base(false) - { } - - protected override void DeliverRemote(ICacheRefresher refresher, MessageType messageType, IEnumerable ids = null, string json = null) - { - throw new NotImplementedException(); - } - } + private ISqlContext SqlContext => GetRequiredService(); + private IContentService ContentService => GetRequiredService(); + private IContentTypeService ContentTypeService => GetRequiredService(); + private IRedirectUrlService RedirectUrlService => GetRequiredService(); + private ILocalizationService LocalizationService => GetRequiredService(); private void AssertJsonStartsWith(int id, string expected) { @@ -134,38 +66,38 @@ namespace Umbraco.Tests.Services [TestCase(ContentVariation.CultureAndSegment, ContentVariation.CultureAndSegment, false)] public void Change_Content_Type_Variation_Clears_Redirects(ContentVariation startingContentTypeVariation, ContentVariation changedContentTypeVariation, bool shouldUrlRedirectsBeCleared) { - var contentType = MockedContentTypes.CreateBasicContentType(); + var contentType = ContentTypeBuilder.CreateBasicContentType(); contentType.Variations = startingContentTypeVariation; - ServiceContext.ContentTypeService.Save(contentType); - var contentType2 = MockedContentTypes.CreateBasicContentType("test"); - ServiceContext.ContentTypeService.Save(contentType2); + ContentTypeService.Save(contentType); + var contentType2 = ContentTypeBuilder.CreateBasicContentType("test"); + ContentTypeService.Save(contentType2); //create some content of this content type - IContent doc = MockedContent.CreateBasicContent(contentType); + IContent doc = ContentBuilder.CreateBasicContent(contentType); doc.Name = "Hello1"; if(startingContentTypeVariation.HasFlag(ContentVariation.Culture)) { doc.SetCultureName(doc.Name, "en-US"); } - ServiceContext.ContentService.Save(doc); + ContentService.Save(doc); - IContent doc2 = MockedContent.CreateBasicContent(contentType2); - ServiceContext.ContentService.Save(doc2); + IContent doc2 = ContentBuilder.CreateBasicContent(contentType2); + ContentService.Save(doc2); - ServiceContext.RedirectUrlService.Register("hello/world", doc.Key); - ServiceContext.RedirectUrlService.Register("hello2/world2", doc2.Key); + RedirectUrlService.Register("hello/world", doc.Key); + 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()); + Assert.AreEqual(1, RedirectUrlService.GetContentRedirectUrls(doc.Key).Count()); + Assert.AreEqual(1, RedirectUrlService.GetContentRedirectUrls(doc2.Key).Count()); //change variation contentType.Variations = changedContentTypeVariation; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); var expectedRedirectUrlCount = shouldUrlRedirectsBeCleared ? 0 : 1; - Assert.AreEqual(expectedRedirectUrlCount, ServiceContext.RedirectUrlService.GetContentRedirectUrls(doc.Key).Count()); - Assert.AreEqual(1, ServiceContext.RedirectUrlService.GetContentRedirectUrls(doc2.Key).Count()); + Assert.AreEqual(expectedRedirectUrlCount, RedirectUrlService.GetContentRedirectUrls(doc.Key).Count()); + Assert.AreEqual(1, RedirectUrlService.GetContentRedirectUrls(doc2.Key).Count()); } [TestCase(ContentVariation.Nothing, ContentVariation.Culture)] @@ -174,19 +106,19 @@ namespace Umbraco.Tests.Services [TestCase(ContentVariation.Segment, ContentVariation.CultureAndSegment)] public void Change_Content_Type_From_No_Culture_To_Culture(ContentVariation from, ContentVariation to) { - var contentType = MockedContentTypes.CreateBasicContentType(); + var contentType = ContentTypeBuilder.CreateBasicContentType(); contentType.Variations = from; var properties = CreatePropertyCollection(("title", from)); contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" }); - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); //create some content of this content type - IContent doc = MockedContent.CreateBasicContent(contentType); + IContent doc = ContentBuilder.CreateBasicContent(contentType); doc.Name = "Hello1"; doc.SetValue("title", "hello world"); - ServiceContext.ContentService.Save(doc); + ContentService.Save(doc); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + doc = ContentService.GetById(doc.Id); //re-get Assert.AreEqual("Hello1", doc.Name); Assert.AreEqual("hello world", doc.GetValue("title")); @@ -195,10 +127,10 @@ namespace Umbraco.Tests.Services //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); + ContentService.Save(doc); contentType.Variations = to; - ServiceContext.ContentTypeService.Save(contentType); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get Assert.AreEqual("Hello2", doc.GetCultureName("en-US")); Assert.AreEqual("hello world", doc.GetValue("title")); //We are not checking against en-US here because properties will remain invariant @@ -207,10 +139,10 @@ 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); + ContentService.Save(doc); contentType.Variations = from; - ServiceContext.ContentTypeService.Save(contentType); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get Assert.AreEqual("Hello3", doc.Name); Assert.AreEqual("hello world", doc.GetValue("title")); @@ -224,19 +156,19 @@ namespace Umbraco.Tests.Services [TestCase(ContentVariation.CultureAndSegment, ContentVariation.Segment)] public void Change_Content_Type_From_Culture_To_No_Culture(ContentVariation startingContentTypeVariation, ContentVariation changeContentTypeVariationTo) { - var contentType = MockedContentTypes.CreateBasicContentType(); + var contentType = ContentTypeBuilder.CreateBasicContentType(); contentType.Variations = startingContentTypeVariation; var properties = CreatePropertyCollection(("title", startingContentTypeVariation)); contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" }); - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); //create some content of this content type - IContent doc = MockedContent.CreateBasicContent(contentType); + IContent doc = ContentBuilder.CreateBasicContent(contentType); doc.SetCultureName("Hello1", "en-US"); doc.SetValue("title", "hello world", "en-US"); - ServiceContext.ContentService.Save(doc); + ContentService.Save(doc); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + doc = ContentService.GetById(doc.Id); //re-get Assert.AreEqual("Hello1", doc.GetCultureName("en-US")); Assert.AreEqual("hello world", doc.GetValue("title", "en-US")); Assert.IsTrue(doc.Edited); @@ -244,10 +176,10 @@ 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); + ContentService.Save(doc); contentType.Variations = changeContentTypeVariationTo; - ServiceContext.ContentTypeService.Save(contentType); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get Assert.AreEqual("Hello2", doc.Name); Assert.AreEqual("hello world", doc.GetValue("title")); @@ -256,10 +188,10 @@ 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); + ContentService.Save(doc); contentType.Variations = startingContentTypeVariation; - ServiceContext.ContentTypeService.Save(contentType); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + ContentTypeService.Save(contentType); + doc = 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, @@ -271,8 +203,8 @@ namespace Umbraco.Tests.Services //we can now switch the property type to be variant and the value can be returned again contentType.PropertyTypes.First().Variations = startingContentTypeVariation; - ServiceContext.ContentTypeService.Save(contentType); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get Assert.AreEqual("Hello3", doc.GetCultureName("en-US")); Assert.AreEqual("hello world", doc.GetValue("title", "en-US")); @@ -298,9 +230,9 @@ namespace Umbraco.Tests.Services [TestCase(ContentVariation.CultureAndSegment, ContentVariation.CultureAndSegment)] public void Preserve_Content_Name_After_Content_Type_Variation_Change(ContentVariation contentTypeVariationFrom, ContentVariation contentTypeVariationTo) { - var contentType = MockedContentTypes.CreateBasicContentType(); + var contentType = ContentTypeBuilder.CreateBasicContentType(); contentType.Variations = contentTypeVariationFrom; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); var invariantContentName = "Content Invariant"; @@ -312,12 +244,12 @@ namespace Umbraco.Tests.Services var globalSettings = new GlobalSettings(); - ServiceContext.LocalizationService.Save(new Language(globalSettings, nlCulture)); + LocalizationService.Save(new Language(globalSettings, nlCulture)); var includeCultureNames = contentType.Variations.HasFlag(ContentVariation.Culture); // Create some content of this content type - IContent doc = MockedContent.CreateBasicContent(contentType); + IContent doc = ContentBuilder.CreateBasicContent(contentType); doc.Name = invariantContentName; if (includeCultureNames) @@ -330,15 +262,15 @@ namespace Umbraco.Tests.Services Assert.Throws(() => doc.SetCultureName(nlContentName, nlCulture)); } - ServiceContext.ContentService.Save(doc); - doc = ServiceContext.ContentService.GetById(doc.Id); + ContentService.Save(doc); + doc = ContentService.GetById(doc.Id); AssertAll(); // Change variation contentType.Variations = contentTypeVariationTo; - ServiceContext.ContentService.Save(doc); - doc = ServiceContext.ContentService.GetById(doc.Id); + ContentService.Save(doc); + doc = ContentService.GetById(doc.Id); AssertAll(); @@ -378,16 +310,16 @@ namespace Umbraco.Tests.Services [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(); + var contentType = ContentTypeBuilder.CreateBasicContentType(); // We test an updated content type so it has to be saved first. - ServiceContext.ContentTypeService.Save(contentType); + 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); + ContentTypeService.Save(contentType); // Check if property type variations have been updated correctly Assert.AreEqual(properties.First().Variations, contentTypeVariation & propertyTypeVariation); @@ -399,28 +331,28 @@ namespace Umbraco.Tests.Services [TestCase(ContentVariation.Segment, ContentVariation.CultureAndSegment)] public void Change_Property_Type_From_Invariant_Variant(ContentVariation invariant, ContentVariation variant) { - var contentType = MockedContentTypes.CreateBasicContentType(); + var contentType = ContentTypeBuilder.CreateBasicContentType(); // 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); + ContentTypeService.Save(contentType); //create some content of this content type - IContent doc = MockedContent.CreateBasicContent(contentType); + IContent doc = ContentBuilder.CreateBasicContent(contentType); doc.SetCultureName("Home", "en-US"); doc.SetValue("title", "hello world"); - ServiceContext.ContentService.Save(doc); + ContentService.Save(doc); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + doc = ContentService.GetById(doc.Id); //re-get Assert.AreEqual("hello world", doc.GetValue("title")); Assert.IsTrue(doc.IsCultureEdited("en-US")); //invariant prop changes show up on default lang Assert.IsTrue(doc.Edited); //change the property type to be variant contentType.PropertyTypes.First().Variations = variant; - ServiceContext.ContentTypeService.Save(contentType); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get Assert.AreEqual("hello world", doc.GetValue("title", "en-US")); Assert.IsTrue(doc.IsCultureEdited("en-US")); @@ -428,8 +360,8 @@ namespace Umbraco.Tests.Services //change back property type to be invariant contentType.PropertyTypes.First().Variations = invariant; - ServiceContext.ContentTypeService.Save(contentType); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get Assert.AreEqual("hello world", doc.GetValue("title")); Assert.IsTrue(doc.IsCultureEdited("en-US")); //invariant prop changes show up on default lang @@ -443,32 +375,32 @@ namespace Umbraco.Tests.Services 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(); + var contentType = ContentTypeBuilder.CreateBasicContentType(); // 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); + ContentTypeService.Save(contentType); //create some content of this content type - IContent doc = MockedContent.CreateBasicContent(contentType); + IContent doc = ContentBuilder.CreateBasicContent(contentType); doc.SetCultureName("Home", "en-US"); doc.SetValue("title", "hello world", "en-US"); - ServiceContext.ContentService.Save(doc); + ContentService.Save(doc); Assert.AreEqual("hello world", doc.GetValue("title", "en-US")); //change the property type to be invariant contentType.PropertyTypes.First().Variations = invariant; - ServiceContext.ContentTypeService.Save(contentType); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get Assert.AreEqual("hello world", doc.GetValue("title")); //change back property type to be variant contentType.PropertyTypes.First().Variations = variant; - ServiceContext.ContentTypeService.Save(contentType); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get Assert.AreEqual("hello world", doc.GetValue("title", "en-US")); } @@ -480,44 +412,44 @@ namespace Umbraco.Tests.Services 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(); + var contentType = ContentTypeBuilder.CreateBasicContentType(); // 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); + ContentTypeService.Save(contentType); //compose this from the other one - var contentType2 = MockedContentTypes.CreateBasicContentType("test"); + var contentType2 = ContentTypeBuilder.CreateBasicContentType("test"); contentType2.Variations = contentType.Variations; contentType2.AddContentType(contentType); - ServiceContext.ContentTypeService.Save(contentType2); + ContentTypeService.Save(contentType2); //create some content of this content type - IContent doc = MockedContent.CreateBasicContent(contentType); + IContent doc = ContentBuilder.CreateBasicContent(contentType); doc.SetCultureName("Home", "en-US"); doc.SetValue("title", "hello world", "en-US"); - ServiceContext.ContentService.Save(doc); + ContentService.Save(doc); - IContent doc2 = MockedContent.CreateBasicContent(contentType2); + IContent doc2 = ContentBuilder.CreateBasicContent(contentType2); doc2.SetCultureName("Home", "en-US"); doc2.SetValue("title", "hello world", "en-US"); - ServiceContext.ContentService.Save(doc2); + ContentService.Save(doc2); //change the property type to be invariant 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 + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get + doc2 = ContentService.GetById(doc2.Id); //re-get Assert.AreEqual("hello world", doc.GetValue("title")); Assert.AreEqual("hello world", doc2.GetValue("title")); //change back property type to be variant 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 + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get + doc2 = ContentService.GetById(doc2.Id); //re-get Assert.AreEqual("hello world", doc.GetValue("title", "en-US")); Assert.AreEqual("hello world", doc2.GetValue("title", "en-US")); @@ -530,43 +462,43 @@ namespace Umbraco.Tests.Services 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(); + var contentType = ContentTypeBuilder.CreateBasicContentType(); contentType.Variations = variant; var properties = CreatePropertyCollection(("title", ContentVariation.Culture)); contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" }); - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); //compose this from the other one - var contentType2 = MockedContentTypes.CreateBasicContentType("test"); + var contentType2 = ContentTypeBuilder.CreateBasicContentType("test"); contentType2.Variations = contentType.Variations; contentType2.AddContentType(contentType); - ServiceContext.ContentTypeService.Save(contentType2); + ContentTypeService.Save(contentType2); //create some content of this content type - IContent doc = MockedContent.CreateBasicContent(contentType); + IContent doc = ContentBuilder.CreateBasicContent(contentType); doc.SetCultureName("Home", "en-US"); doc.SetValue("title", "hello world", "en-US"); - ServiceContext.ContentService.Save(doc); + ContentService.Save(doc); - IContent doc2 = MockedContent.CreateBasicContent(contentType2); + IContent doc2 = ContentBuilder.CreateBasicContent(contentType2); doc2.SetCultureName("Home", "en-US"); doc2.SetValue("title", "hello world", "en-US"); - ServiceContext.ContentService.Save(doc2); + ContentService.Save(doc2); //change the content type to be invariant contentType.Variations = invariant; - ServiceContext.ContentTypeService.Save(contentType); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get - doc2 = ServiceContext.ContentService.GetById(doc2.Id); //re-get + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get + doc2 = ContentService.GetById(doc2.Id); //re-get Assert.AreEqual("hello world", doc.GetValue("title")); Assert.AreEqual("hello world", doc2.GetValue("title")); //change back content type to be variant contentType.Variations = variant; - ServiceContext.ContentTypeService.Save(contentType); - doc = ServiceContext.ContentService.GetById(doc.Id); //re-get - doc2 = ServiceContext.ContentService.GetById(doc2.Id); //re-get + ContentTypeService.Save(contentType); + doc = ContentService.GetById(doc.Id); //re-get + doc2 = ContentService.GetById(doc2.Id); //re-get //this will be null because the doc type was changed back to variant but it's property types don't get changed back Assert.IsNull(doc.GetValue("title", "en-US")); @@ -578,7 +510,7 @@ namespace Umbraco.Tests.Services { // one simple content type, variant, with both variant and invariant properties // can change it to invariant and back - + GetRequiredService(); //hack to ensure events are initialized CreateFrenchAndEnglishLangs(); var contentType = CreateContentType(ContentVariation.Culture); @@ -588,7 +520,7 @@ namespace Umbraco.Tests.Services ("value2", ContentVariation.Nothing)); contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" }); - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); var document = (IContent)new Content("document", -1, contentType); document.SetCultureName("doc1en", "en"); @@ -596,9 +528,9 @@ namespace Umbraco.Tests.Services document.SetValue("value1", "v1en", "en"); document.SetValue("value1", "v1fr", "fr"); document.SetValue("value2", "v2"); - ServiceContext.ContentService.Save(document); + ContentService.Save(document); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -612,9 +544,9 @@ namespace Umbraco.Tests.Services // switch content type to Nothing contentType.Variations = ContentVariation.Nothing; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.IsNull(document.GetCultureName("en")); Assert.IsNull(document.GetCultureName("fr")); @@ -629,9 +561,9 @@ namespace Umbraco.Tests.Services // switch content back to Culture contentType.Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -646,9 +578,9 @@ namespace Umbraco.Tests.Services // switch property back to Culture contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -658,7 +590,7 @@ namespace Umbraco.Tests.Services Console.WriteLine(GetJson(document.Id)); AssertJsonStartsWith(document.Id, - "{'pd':{'value1':[{'c':'en','v':'v1en'},{'c':'fr','v':'v1fr'}],'value2':[{'v':'v2'}]},'cd':"); + "{'pd':{'value1':[{'c':'fr','v':'v1fr'},{'c':'en','v':'v1en'}],'value2':[{'v':'v2'}]},'cd':"); } [Test] @@ -667,13 +599,14 @@ namespace Umbraco.Tests.Services // one simple content type, invariant // can change it to variant and back // can then switch one property to variant + GetRequiredService(); //hack to ensure events are initialized var globalSettings = new GlobalSettings(); var languageEn = new Language(globalSettings, "en") { IsDefault = true }; - ServiceContext.LocalizationService.Save(languageEn); + LocalizationService.Save(languageEn); var languageFr = new Language(globalSettings, "fr"); - ServiceContext.LocalizationService.Save(languageFr); + LocalizationService.Save(languageFr); var contentType = CreateContentType(ContentVariation.Nothing); @@ -682,15 +615,15 @@ namespace Umbraco.Tests.Services ("value2", ContentVariation.Nothing)); contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" }); - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); var document = (IContent) new Content("document", -1, contentType); document.Name = "doc1"; document.SetValue("value1", "v1"); document.SetValue("value2", "v2"); - ServiceContext.ContentService.Save(document); + ContentService.Save(document); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1", document.Name); Assert.IsNull(document.GetCultureName("en")); Assert.IsNull(document.GetCultureName("fr")); @@ -705,9 +638,9 @@ namespace Umbraco.Tests.Services // switch content type to Culture contentType.Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1", document.GetCultureName("en")); Assert.IsNull(document.GetCultureName("fr")); Assert.IsNull(document.GetValue("value1", "en")); @@ -721,9 +654,9 @@ namespace Umbraco.Tests.Services // switch property to Culture contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1", document.GetCultureName("en")); Assert.IsNull(document.GetCultureName("fr")); Assert.AreEqual("v1", document.GetValue("value1", "en")); @@ -736,9 +669,9 @@ namespace Umbraco.Tests.Services // switch content back to Nothing contentType.Variations = ContentVariation.Nothing; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1", document.Name); Assert.IsNull(document.GetCultureName("en")); Assert.IsNull(document.GetCultureName("fr")); @@ -757,7 +690,7 @@ namespace Umbraco.Tests.Services { // one simple content type, variant, with both variant and invariant properties // can change an invariant property to variant and back - + GetRequiredService(); //hack to ensure events are initialized CreateFrenchAndEnglishLangs(); var contentType = CreateContentType(ContentVariation.Culture); @@ -767,7 +700,7 @@ namespace Umbraco.Tests.Services ("value2", ContentVariation.Nothing)); contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" }); - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); var document = (IContent)new Content("document", -1, contentType); document.SetCultureName("doc1en", "en"); @@ -775,9 +708,9 @@ namespace Umbraco.Tests.Services document.SetValue("value1", "v1en", "en"); document.SetValue("value1", "v1fr", "fr"); document.SetValue("value2", "v2"); - ServiceContext.ContentService.Save(document); + ContentService.Save(document); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -791,9 +724,9 @@ namespace Umbraco.Tests.Services // switch property type to Nothing contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = ContentVariation.Nothing; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -808,9 +741,9 @@ namespace Umbraco.Tests.Services // switch property back to Culture contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -820,13 +753,13 @@ namespace Umbraco.Tests.Services Console.WriteLine(GetJson(document.Id)); AssertJsonStartsWith(document.Id, - "{'pd':{'value1':[{'c':'en','v':'v1en'},{'c':'fr','v':'v1fr'}],'value2':[{'v':'v2'}]},'cd':"); + "{'pd':{'value1':[{'c':'fr','v':'v1fr'},{'c':'en','v':'v1en'}],'value2':[{'v':'v2'}]},'cd':"); // switch other property to Culture contentType.PropertyTypes.First(x => x.Alias == "value2").Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -838,7 +771,7 @@ namespace Umbraco.Tests.Services Console.WriteLine(GetJson(document.Id)); AssertJsonStartsWith(document.Id, - "{'pd':{'value1':[{'c':'en','v':'v1en'},{'c':'fr','v':'v1fr'}],'value2':[{'c':'en','v':'v2'}]},'cd':"); + "{'pd':{'value1':[{'c':'fr','v':'v1fr'},{'c':'en','v':'v1en'}],'value2':[{'c':'en','v':'v2'}]},'cd':"); } [TestCase(ContentVariation.Culture, ContentVariation.Nothing)] @@ -857,25 +790,25 @@ namespace Umbraco.Tests.Services var properties = CreatePropertyCollection(("value1", variant)); contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" }); - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); IContent document = new Content("document", -1, contentType); document.SetCultureName("doc1en", "en"); document.SetCultureName("doc1fr", "fr"); document.SetValue("value1", "v1en-init", "en"); document.SetValue("value1", "v1fr-init", "fr"); - ServiceContext.ContentService.SaveAndPublish(document); //all values are published which means the document is not 'edited' + ContentService.SaveAndPublish(document); //all values are published which means the document is not 'edited' - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.IsFalse(document.IsCultureEdited("en")); Assert.IsFalse(document.IsCultureEdited("fr")); Assert.IsFalse(document.Edited); document.SetValue("value1", "v1en", "en"); //change the property culture value, so now this culture will be edited document.SetValue("value1", "v1fr", "fr"); //change the property culture value, so now this culture will be edited - ServiceContext.ContentService.Save(document); + ContentService.Save(document); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -889,18 +822,18 @@ namespace Umbraco.Tests.Services // switch property type to Invariant contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = invariant; - ServiceContext.ContentTypeService.Save(contentType); //This is going to have to re-normalize the "Edited" flag + ContentTypeService.Save(contentType); //This is going to have to re-normalize the "Edited" flag - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.IsTrue(document.IsCultureEdited("en")); //This will remain true because there is now a pending change for the invariant property data which is flagged under the default lang Assert.IsFalse(document.IsCultureEdited("fr")); //This will be false because nothing has changed for this culture and the property no longer reflects variant changes Assert.IsTrue(document.Edited); //update the invariant value and publish document.SetValue("value1", "v1inv"); - ServiceContext.ContentService.SaveAndPublish(document); + ContentService.SaveAndPublish(document); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -916,9 +849,9 @@ namespace Umbraco.Tests.Services // switch property back to Culture contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = variant; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("v1inv", document.GetValue("value1", "en")); //The invariant property value gets copied over to the default language Assert.AreEqual("v1inv", document.GetValue("value1", "en", published: true)); Assert.AreEqual("v1fr", document.GetValue("value1", "fr")); //values are still retained @@ -930,9 +863,9 @@ namespace Umbraco.Tests.Services // publish again document.SetValue("value1", "v1en2", "en"); //update the value now that it's variant again document.SetValue("value1", "v1fr2", "fr"); //update the value now that it's variant again - ServiceContext.ContentService.SaveAndPublish(document); + ContentService.SaveAndPublish(document); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -960,23 +893,23 @@ namespace Umbraco.Tests.Services var properties = CreatePropertyCollection(("value1", invariant)); contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" }); - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); var document = (IContent)new Content("document", -1, contentType); document.SetCultureName("doc1en", "en"); document.SetCultureName("doc1fr", "fr"); document.SetValue("value1", "v1en-init"); - ServiceContext.ContentService.SaveAndPublish(document); //all values are published which means the document is not 'edited' + ContentService.SaveAndPublish(document); //all values are published which means the document is not 'edited' - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.IsFalse(document.IsCultureEdited("en")); Assert.IsFalse(document.IsCultureEdited("fr")); Assert.IsFalse(document.Edited); document.SetValue("value1", "v1en"); //change the property value, so now the invariant (default) culture will be edited - ServiceContext.ContentService.Save(document); + ContentService.Save(document); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -988,18 +921,18 @@ namespace Umbraco.Tests.Services // switch property type to 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 + ContentTypeService.Save(contentType); //This is going to have to re-normalize the "Edited" flag - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.IsTrue(document.IsCultureEdited("en")); //Remains true Assert.IsFalse(document.IsCultureEdited("fr")); //False because no french property has ever been edited Assert.IsTrue(document.Edited); //update the culture value and publish document.SetValue("value1", "v1en2", "en"); - ServiceContext.ContentService.SaveAndPublish(document); + ContentService.SaveAndPublish(document); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("doc1en", document.Name); Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); @@ -1013,9 +946,9 @@ namespace Umbraco.Tests.Services // switch property back to Invariant contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = invariant; - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); - document = ServiceContext.ContentService.GetById(document.Id); + document = ContentService.GetById(document.Id); Assert.AreEqual("v1en2", document.GetValue("value1")); //The variant property value gets copied over to the invariant Assert.AreEqual("v1en2", document.GetValue("value1", published: true)); Assert.IsNull(document.GetValue("value1", "fr")); //The values are there but the business logic returns null @@ -1034,6 +967,8 @@ namespace Umbraco.Tests.Services // can change the composing content type to invariant and back // can change the composed content type to invariant and back + + GetRequiredService(); //hack to ensure events are initialized CreateFrenchAndEnglishLangs(); var composing = CreateContentType(ContentVariation.Culture, "composing"); @@ -1043,7 +978,7 @@ namespace Umbraco.Tests.Services ("value12", ContentVariation.Nothing)); composing.PropertyGroups.Add(new PropertyGroup(properties1) { Name = "Content" }); - ServiceContext.ContentTypeService.Save(composing); + ContentTypeService.Save(composing); var composed = CreateContentType(ContentVariation.Culture, "composed"); @@ -1053,7 +988,7 @@ namespace Umbraco.Tests.Services composed.PropertyGroups.Add(new PropertyGroup(properties2) { Name = "Content" }); composed.AddContentType(composing); - ServiceContext.ContentTypeService.Save(composed); + ContentTypeService.Save(composed); var document = (IContent) new Content("document", -1, composed); document.SetCultureName("doc1en", "en"); @@ -1064,7 +999,7 @@ namespace Umbraco.Tests.Services document.SetValue("value21", "v21en", "en"); document.SetValue("value21", "v21fr", "fr"); document.SetValue("value22", "v22"); - ServiceContext.ContentService.Save(document); + ContentService.Save(document); // both value11 and value21 are variant Console.WriteLine(GetJson(document.Id)); @@ -1072,7 +1007,7 @@ namespace Umbraco.Tests.Services "{'pd':{'value11':[{'c':'en','v':'v11en'},{'c':'fr','v':'v11fr'}],'value12':[{'v':'v12'}],'value21':[{'c':'en','v':'v21en'},{'c':'fr','v':'v21fr'}],'value22':[{'v':'v22'}]},'cd':"); composed.Variations = ContentVariation.Nothing; - ServiceContext.ContentTypeService.Save(composed); + ContentTypeService.Save(composed); // both value11 and value21 are invariant Console.WriteLine(GetJson(document.Id)); @@ -1080,7 +1015,7 @@ namespace Umbraco.Tests.Services "{'pd':{'value11':[{'v':'v11en'}],'value12':[{'v':'v12'}],'value21':[{'v':'v21en'}],'value22':[{'v':'v22'}]},'cd':"); composed.Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(composed); + ContentTypeService.Save(composed); // value11 is variant again, but value21 is still invariant Console.WriteLine(GetJson(document.Id)); @@ -1088,36 +1023,36 @@ namespace Umbraco.Tests.Services "{'pd':{'value11':[{'c':'en','v':'v11en'},{'c':'fr','v':'v11fr'}],'value12':[{'v':'v12'}],'value21':[{'v':'v21en'}],'value22':[{'v':'v22'}]},'cd':"); composed.PropertyTypes.First(x => x.Alias == "value21").Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(composed); + ContentTypeService.Save(composed); // we can make it variant again Console.WriteLine(GetJson(document.Id)); AssertJsonStartsWith(document.Id, - "{'pd':{'value11':[{'c':'en','v':'v11en'},{'c':'fr','v':'v11fr'}],'value12':[{'v':'v12'}],'value21':[{'c':'en','v':'v21en'},{'c':'fr','v':'v21fr'}],'value22':[{'v':'v22'}]},'cd':"); + "{'pd':{'value11':[{'c':'en','v':'v11en'},{'c':'fr','v':'v11fr'}],'value12':[{'v':'v12'}],'value21':[{'c':'fr','v':'v21fr'},{'c':'en','v':'v21en'}],'value22':[{'v':'v22'}]},'cd':"); composing.Variations = ContentVariation.Nothing; - ServiceContext.ContentTypeService.Save(composing); + ContentTypeService.Save(composing); // value11 is invariant Console.WriteLine(GetJson(document.Id)); AssertJsonStartsWith(document.Id, - "{'pd':{'value11':[{'v':'v11en'}],'value12':[{'v':'v12'}],'value21':[{'c':'en','v':'v21en'},{'c':'fr','v':'v21fr'}],'value22':[{'v':'v22'}]},'cd':"); + "{'pd':{'value11':[{'v':'v11en'}],'value12':[{'v':'v12'}],'value21':[{'c':'fr','v':'v21fr'},{'c':'en','v':'v21en'}],'value22':[{'v':'v22'}]},'cd':"); composing.Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(composing); + ContentTypeService.Save(composing); // value11 is still invariant Console.WriteLine(GetJson(document.Id)); AssertJsonStartsWith(document.Id, - "{'pd':{'value11':[{'v':'v11en'}],'value12':[{'v':'v12'}],'value21':[{'c':'en','v':'v21en'},{'c':'fr','v':'v21fr'}],'value22':[{'v':'v22'}]},'cd':"); + "{'pd':{'value11':[{'v':'v11en'}],'value12':[{'v':'v12'}],'value21':[{'c':'fr','v':'v21fr'},{'c':'en','v':'v21en'}],'value22':[{'v':'v22'}]},'cd':"); composing.PropertyTypes.First(x => x.Alias == "value11").Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(composing); + ContentTypeService.Save(composing); // we can make it variant again Console.WriteLine(GetJson(document.Id)); AssertJsonStartsWith(document.Id, - "{'pd':{'value11':[{'c':'en','v':'v11en'},{'c':'fr','v':'v11fr'}],'value12':[{'v':'v12'}],'value21':[{'c':'en','v':'v21en'},{'c':'fr','v':'v21fr'}],'value22':[{'v':'v22'}]},'cd':"); + "{'pd':{'value11':[{'c':'fr','v':'v11fr'},{'c':'en','v':'v11en'}],'value12':[{'v':'v12'}],'value21':[{'c':'fr','v':'v21fr'},{'c':'en','v':'v21en'}],'value22':[{'v':'v22'}]},'cd':"); } [Test] @@ -1129,6 +1064,7 @@ namespace Umbraco.Tests.Services // can change the composing content type to invariant and back // can change the variant composed content type to invariant and back + GetRequiredService(); //hack to ensure events are initialized CreateFrenchAndEnglishLangs(); var composing = CreateContentType(ContentVariation.Culture, "composing"); @@ -1138,7 +1074,7 @@ namespace Umbraco.Tests.Services ("value12", ContentVariation.Nothing)); composing.PropertyGroups.Add(new PropertyGroup(properties1) { Name = "Content" }); - ServiceContext.ContentTypeService.Save(composing); + ContentTypeService.Save(composing); var composed1 = CreateContentType(ContentVariation.Culture, "composed1"); @@ -1148,7 +1084,7 @@ namespace Umbraco.Tests.Services composed1.PropertyGroups.Add(new PropertyGroup(properties2) { Name = "Content" }); composed1.AddContentType(composing); - ServiceContext.ContentTypeService.Save(composed1); + ContentTypeService.Save(composed1); var composed2 = CreateContentType(ContentVariation.Nothing, "composed2"); @@ -1158,7 +1094,7 @@ namespace Umbraco.Tests.Services composed2.PropertyGroups.Add(new PropertyGroup(properties3) { Name = "Content" }); composed2.AddContentType(composing); - ServiceContext.ContentTypeService.Save(composed2); + ContentTypeService.Save(composed2); var document1 = (IContent) new Content ("document1", -1, composed1); document1.SetCultureName("doc1en", "en"); @@ -1169,7 +1105,7 @@ namespace Umbraco.Tests.Services document1.SetValue("value21", "v21en", "en"); document1.SetValue("value21", "v21fr", "fr"); document1.SetValue("value22", "v22"); - ServiceContext.ContentService.Save(document1); + ContentService.Save(document1); var document2 = (IContent)new Content("document2", -1, composed2); document2.Name = "doc2"; @@ -1177,7 +1113,7 @@ namespace Umbraco.Tests.Services document2.SetValue("value12", "v12"); document2.SetValue("value31", "v31"); document2.SetValue("value32", "v32"); - ServiceContext.ContentService.Save(document2); + ContentService.Save(document2); // both value11 and value21 are variant Console.WriteLine(GetJson(document1.Id)); @@ -1189,7 +1125,7 @@ namespace Umbraco.Tests.Services "{'pd':{'value11':[{'v':'v11'}],'value12':[{'v':'v12'}],'value31':[{'v':'v31'}],'value32':[{'v':'v32'}]},'cd':"); composed1.Variations = ContentVariation.Nothing; - ServiceContext.ContentTypeService.Save(composed1); + ContentTypeService.Save(composed1); // both value11 and value21 are invariant Console.WriteLine(GetJson(document1.Id)); @@ -1201,7 +1137,7 @@ namespace Umbraco.Tests.Services "{'pd':{'value11':[{'v':'v11'}],'value12':[{'v':'v12'}],'value31':[{'v':'v31'}],'value32':[{'v':'v32'}]},'cd':"); composed1.Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(composed1); + ContentTypeService.Save(composed1); // value11 is variant again, but value21 is still invariant Console.WriteLine(GetJson(document1.Id)); @@ -1213,48 +1149,48 @@ namespace Umbraco.Tests.Services "{'pd':{'value11':[{'v':'v11'}],'value12':[{'v':'v12'}],'value31':[{'v':'v31'}],'value32':[{'v':'v32'}]},'cd':"); composed1.PropertyTypes.First(x => x.Alias == "value21").Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(composed1); + ContentTypeService.Save(composed1); // we can make it variant again Console.WriteLine(GetJson(document1.Id)); AssertJsonStartsWith(document1.Id, - "{'pd':{'value11':[{'c':'en','v':'v11en'},{'c':'fr','v':'v11fr'}],'value12':[{'v':'v12'}],'value21':[{'c':'en','v':'v21en'},{'c':'fr','v':'v21fr'}],'value22':[{'v':'v22'}]},'cd':"); + "{'pd':{'value11':[{'c':'en','v':'v11en'},{'c':'fr','v':'v11fr'}],'value12':[{'v':'v12'}],'value21':[{'c':'fr','v':'v21fr'},{'c':'en','v':'v21en'}],'value22':[{'v':'v22'}]},'cd':"); Console.WriteLine(GetJson(document2.Id)); AssertJsonStartsWith(document2.Id, "{'pd':{'value11':[{'v':'v11'}],'value12':[{'v':'v12'}],'value31':[{'v':'v31'}],'value32':[{'v':'v32'}]},'cd':"); composing.Variations = ContentVariation.Nothing; - ServiceContext.ContentTypeService.Save(composing); + ContentTypeService.Save(composing); // value11 is invariant Console.WriteLine(GetJson(document1.Id)); AssertJsonStartsWith(document1.Id, - "{'pd':{'value11':[{'v':'v11en'}],'value12':[{'v':'v12'}],'value21':[{'c':'en','v':'v21en'},{'c':'fr','v':'v21fr'}],'value22':[{'v':'v22'}]},'cd':"); + "{'pd':{'value11':[{'v':'v11en'}],'value12':[{'v':'v12'}],'value21':[{'c':'fr','v':'v21fr'},{'c':'en','v':'v21en'}],'value22':[{'v':'v22'}]},'cd':"); Console.WriteLine(GetJson(document2.Id)); AssertJsonStartsWith(document2.Id, "{'pd':{'value11':[{'v':'v11'}],'value12':[{'v':'v12'}],'value31':[{'v':'v31'}],'value32':[{'v':'v32'}]},'cd':"); composing.Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(composing); + ContentTypeService.Save(composing); // value11 is still invariant Console.WriteLine(GetJson(document1.Id)); AssertJsonStartsWith(document1.Id, - "{'pd':{'value11':[{'v':'v11en'}],'value12':[{'v':'v12'}],'value21':[{'c':'en','v':'v21en'},{'c':'fr','v':'v21fr'}],'value22':[{'v':'v22'}]},'cd':"); + "{'pd':{'value11':[{'v':'v11en'}],'value12':[{'v':'v12'}],'value21':[{'c':'fr','v':'v21fr'},{'c':'en','v':'v21en'}],'value22':[{'v':'v22'}]},'cd':"); Console.WriteLine(GetJson(document2.Id)); AssertJsonStartsWith(document2.Id, "{'pd':{'value11':[{'v':'v11'}],'value12':[{'v':'v12'}],'value31':[{'v':'v31'}],'value32':[{'v':'v32'}]},'cd':"); composing.PropertyTypes.First(x => x.Alias == "value11").Variations = ContentVariation.Culture; - ServiceContext.ContentTypeService.Save(composing); + ContentTypeService.Save(composing); // we can make it variant again Console.WriteLine(GetJson(document1.Id)); AssertJsonStartsWith(document1.Id, - "{'pd':{'value11':[{'c':'en','v':'v11en'},{'c':'fr','v':'v11fr'}],'value12':[{'v':'v12'}],'value21':[{'c':'en','v':'v21en'},{'c':'fr','v':'v21fr'}],'value22':[{'v':'v22'}]},'cd':"); + "{'pd':{'value11':[{'c':'fr','v':'v11fr'},{'c':'en','v':'v11en'}],'value12':[{'v':'v12'}],'value21':[{'c':'fr','v':'v21fr'},{'c':'en','v':'v21en'}],'value22':[{'v':'v22'}]},'cd':"); Console.WriteLine(GetJson(document2.Id)); AssertJsonStartsWith(document2.Id, @@ -1265,9 +1201,9 @@ namespace Umbraco.Tests.Services { var globalSettings = new GlobalSettings(); var languageEn = new Language(globalSettings, "en") { IsDefault = true }; - ServiceContext.LocalizationService.Save(languageEn); + LocalizationService.Save(languageEn); var languageFr = new Language(globalSettings, "fr"); - ServiceContext.LocalizationService.Save(languageFr); + LocalizationService.Save(languageFr); } private IContentType CreateContentType(ContentVariation variance, string alias = "contentType") => new ContentType(ShortStringHelper, -1) diff --git a/src/Umbraco.Tests.Integration/Services/DataTypeServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/DataTypeServiceTests.cs similarity index 98% rename from src/Umbraco.Tests.Integration/Services/DataTypeServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/DataTypeServiceTests.cs index 160769439d..33762f9b3c 100644 --- a/src/Umbraco.Tests.Integration/Services/DataTypeServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/DataTypeServiceTests.cs @@ -9,7 +9,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { /// /// Tests covering the DataTypeService diff --git a/src/Umbraco.Tests.Integration/Services/EntityServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/EntityServiceTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/EntityServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/EntityServiceTests.cs index 64e7cea8dc..da933bb9d7 100644 --- a/src/Umbraco.Tests.Integration/Services/EntityServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/EntityServiceTests.cs @@ -13,7 +13,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { /// /// Tests covering the EntityService diff --git a/src/Umbraco.Tests.Integration/Services/EntityXmlSerializerTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/EntityXmlSerializerTests.cs similarity index 96% rename from src/Umbraco.Tests.Integration/Services/EntityXmlSerializerTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/EntityXmlSerializerTests.cs index 5bc16a4cdb..a0068f8c3d 100644 --- a/src/Umbraco.Tests.Integration/Services/EntityXmlSerializerTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/EntityXmlSerializerTests.cs @@ -7,11 +7,11 @@ using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -using Umbraco.Tests.Integration.Services.Importing; using Umbraco.Tests.Integration.Testing; +using Umbraco.Tests.Integration.Umbraco.Infrastructure.Services.Importing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] diff --git a/src/Umbraco.Tests.Integration/Services/FileServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/FileServiceTests.cs similarity index 97% rename from src/Umbraco.Tests.Integration/Services/FileServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/FileServiceTests.cs index 8a4a0535b6..1820573cc2 100644 --- a/src/Umbraco.Tests.Integration/Services/FileServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/FileServiceTests.cs @@ -6,7 +6,7 @@ using Umbraco.Core.Services; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [Apartment(ApartmentState.STA)] diff --git a/src/Umbraco.Tests.Integration/Services/Importing/Dictionary-Package.xml b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/Importing/Dictionary-Package.xml similarity index 100% rename from src/Umbraco.Tests.Integration/Services/Importing/Dictionary-Package.xml rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/Importing/Dictionary-Package.xml diff --git a/src/Umbraco.Tests.Integration/Services/Importing/ImportResources.Designer.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/Importing/ImportResources.Designer.cs similarity index 94% rename from src/Umbraco.Tests.Integration/Services/Importing/ImportResources.Designer.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/Importing/ImportResources.Designer.cs index 4925956fb8..488108ebda 100644 --- a/src/Umbraco.Tests.Integration/Services/Importing/ImportResources.Designer.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/Importing/ImportResources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Umbraco.Tests.Integration.Services.Importing { +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services.Importing { using System; @@ -39,7 +39,8 @@ namespace Umbraco.Tests.Integration.Services.Importing { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Umbraco.Tests.Integration.Services.Importing.ImportResources", typeof(ImportResources).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Umbraco.Tests.Integration.Umbraco.Infrastructure.Services.Importing.ImportResourc" + + "es", typeof(ImportResources).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/Umbraco.Tests.Integration/Services/Importing/ImportResources.resx b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/Importing/ImportResources.resx similarity index 100% rename from src/Umbraco.Tests.Integration/Services/Importing/ImportResources.resx rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/Importing/ImportResources.resx diff --git a/src/Umbraco.Tests.Integration/Services/KeyValueServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/KeyValueServiceTests.cs similarity index 97% rename from src/Umbraco.Tests.Integration/Services/KeyValueServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/KeyValueServiceTests.cs index 8694e88395..8248e89dc2 100644 --- a/src/Umbraco.Tests.Integration/Services/KeyValueServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/KeyValueServiceTests.cs @@ -4,7 +4,7 @@ using Umbraco.Core.Services; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { /// /// Tests covering methods in the KeyValueService class. diff --git a/src/Umbraco.Tests.Integration/Services/LocalizationServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/LocalizationServiceTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/LocalizationServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/LocalizationServiceTests.cs index a2847b64fe..5076a3bbf7 100644 --- a/src/Umbraco.Tests.Integration/Services/LocalizationServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/LocalizationServiceTests.cs @@ -12,7 +12,7 @@ using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { /// /// Tests covering all methods in the LocalizationService class. diff --git a/src/Umbraco.Tests.Integration/Services/MacroServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MacroServiceTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/MacroServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MacroServiceTests.cs index ed663207b4..d2c1e3b7fc 100644 --- a/src/Umbraco.Tests.Integration/Services/MacroServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MacroServiceTests.cs @@ -14,7 +14,7 @@ using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [Apartment(ApartmentState.STA)] diff --git a/src/Umbraco.Tests.Integration/Services/MediaServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MediaServiceTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/MediaServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MediaServiceTests.cs index a6b67c8b59..c3a2866d2e 100644 --- a/src/Umbraco.Tests.Integration/Services/MediaServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MediaServiceTests.cs @@ -13,7 +13,7 @@ using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [Apartment(ApartmentState.STA)] diff --git a/src/Umbraco.Tests.Integration/Services/MediaTypeServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MediaTypeServiceTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/MediaTypeServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MediaTypeServiceTests.cs index 3e4bbfa611..8a38bdc6eb 100644 --- a/src/Umbraco.Tests.Integration/Services/MediaTypeServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MediaTypeServiceTests.cs @@ -11,7 +11,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [Apartment(ApartmentState.STA)] diff --git a/src/Umbraco.Tests.Integration/Services/MemberGroupServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MemberGroupServiceTests.cs similarity index 93% rename from src/Umbraco.Tests.Integration/Services/MemberGroupServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MemberGroupServiceTests.cs index 7bca819915..e0119bccb4 100644 --- a/src/Umbraco.Tests.Integration/Services/MemberGroupServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MemberGroupServiceTests.cs @@ -7,7 +7,7 @@ using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [Apartment(ApartmentState.STA)] diff --git a/src/Umbraco.Tests.Integration/Services/MemberServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MemberServiceTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/MemberServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MemberServiceTests.cs index f58967cf7b..d17eead162 100644 --- a/src/Umbraco.Tests.Integration/Services/MemberServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MemberServiceTests.cs @@ -19,7 +19,7 @@ using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; using Umbraco.Web.PublishedCache.NuCache; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [Category("Slow")] @@ -34,7 +34,7 @@ namespace Umbraco.Tests.Integration.Services public void SetupTest() { // TODO: remove this once IPublishedSnapShotService has been implemented with nucache. - Core.Services.Implement.MemberTypeService.ClearScopeEvents(); + global::Umbraco.Core.Services.Implement.MemberTypeService.ClearScopeEvents(); } [Test] diff --git a/src/Umbraco.Tests.Integration/Services/MemberTypeServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MemberTypeServiceTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/MemberTypeServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MemberTypeServiceTests.cs index bdc4c1f9a2..5c61501a10 100644 --- a/src/Umbraco.Tests.Integration/Services/MemberTypeServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MemberTypeServiceTests.cs @@ -9,7 +9,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [Apartment(ApartmentState.STA)] @@ -23,7 +23,7 @@ namespace Umbraco.Tests.Integration.Services public void SetupTest() { // TODO: remove this once IPublishedSnapShotService has been implemented with nucache. - Core.Services.Implement.MemberTypeService.ClearScopeEvents(); + global::Umbraco.Core.Services.Implement.MemberTypeService.ClearScopeEvents(); } [Test] diff --git a/src/Umbraco.Tests.Integration/Services/PublicAccessServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/PublicAccessServiceTests.cs similarity index 98% rename from src/Umbraco.Tests.Integration/Services/PublicAccessServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/PublicAccessServiceTests.cs index b02bdb9b70..9b46a37245 100644 --- a/src/Umbraco.Tests.Integration/Services/PublicAccessServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/PublicAccessServiceTests.cs @@ -8,7 +8,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [Apartment(ApartmentState.STA)] diff --git a/src/Umbraco.Tests.Integration/Services/RelationServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/RelationServiceTests.cs similarity index 98% rename from src/Umbraco.Tests.Integration/Services/RelationServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/RelationServiceTests.cs index 9fe4867fc2..3196b54201 100644 --- a/src/Umbraco.Tests.Integration/Services/RelationServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/RelationServiceTests.cs @@ -6,14 +6,11 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Services; -using Umbraco.Core.Services.Implement; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [Apartment(ApartmentState.STA)] diff --git a/src/Umbraco.Tests.Integration/Services/TagServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/TagServiceTests.cs similarity index 98% rename from src/Umbraco.Tests.Integration/Services/TagServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/TagServiceTests.cs index f84dbfb74a..a0632668aa 100644 --- a/src/Umbraco.Tests.Integration/Services/TagServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/TagServiceTests.cs @@ -8,10 +8,9 @@ using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Integration.Testing; -using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { /// /// Tests covering methods in the TagService class. diff --git a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ThreadSafetyServiceTest.cs similarity index 90% rename from src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ThreadSafetyServiceTest.cs index 33ee2f737a..c36968adeb 100644 --- a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ThreadSafetyServiceTest.cs @@ -9,11 +9,13 @@ using Umbraco.Core.Models; using Umbraco.Core.Scoping; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; +using Umbraco.Tests.Common.Builders; +using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { // these tests tend to fail from time to time esp. on VSTS // @@ -30,20 +32,20 @@ namespace Umbraco.Tests.Services [TestFixture] [Apartment(ApartmentState.STA)] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class ThreadSafetyServiceTest : TestWithDatabaseBase + public class ThreadSafetyServiceTest : UmbracoIntegrationTest { - public override void SetUp() + private IContentService ContentService => GetRequiredService(); + private IMediaService MediaService => GetRequiredService(); + private IContentTypeService ContentTypeService => GetRequiredService(); + + [SetUp] + public void SetUp() { - base.SetUp(); CreateTestData(); } - // not sure this is doing anything really - protected override string GetDbConnectionString() - { - // need a longer timeout for tests? - return base.GetDbConnectionString() + "default lock timeout=60000;"; - } + protected override string TestDBConnectionString => base.TestDBConnectionString + "default lock timeout=60000;"; + private const int MaxThreadCount = 20; @@ -99,7 +101,7 @@ namespace Umbraco.Tests.Services Assert.Ignore("Do not run on VSTS."); // the ServiceContext in that each repository in a service (i.e. ContentService) is a singleton - var contentService = (ContentService)ServiceContext.ContentService; + var contentService = (ContentService)ContentService; var threads = new List(); var exceptions = new List(); @@ -167,7 +169,7 @@ namespace Umbraco.Tests.Services if (Environment.GetEnvironmentVariable("UMBRACO_TMP") != null) Assert.Ignore("Do not run on VSTS."); // mimick the ServiceContext in that each repository in a service (i.e. ContentService) is a singleton - var mediaService = (MediaService)ServiceContext.MediaService; + var mediaService = (MediaService)MediaService; var threads = new List(); var exceptions = new List(); @@ -228,9 +230,9 @@ namespace Umbraco.Tests.Services public void CreateTestData() { // Create and Save ContentType "umbTextpage" -> 1045 - var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage", "Textpage"); + var contentType = ContentTypeBuilder.CreateSimpleContentType("umbTextpage", "Textpage"); contentType.Key = new Guid("1D3A8E6E-2EA9-4CC1-B229-1AEE19821522"); - ServiceContext.ContentTypeService.Save(contentType); + ContentTypeService.Save(contentType); } } } diff --git a/src/Umbraco.Tests.Integration/Services/UserServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/UserServiceTests.cs similarity index 99% rename from src/Umbraco.Tests.Integration/Services/UserServiceTests.cs rename to src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/UserServiceTests.cs index 802bfd9e1b..8b5189378d 100644 --- a/src/Umbraco.Tests.Integration/Services/UserServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/UserServiceTests.cs @@ -13,13 +13,11 @@ using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; using Umbraco.Tests.Common.Builders; -using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Tests.Integration.Testing; -using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.Testing; using Umbraco.Web.Actions; -namespace Umbraco.Tests.Integration.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { /// /// Tests covering the UserService diff --git a/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj index 4300c7650a..b483d690f4 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj +++ b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj @@ -18,11 +18,20 @@ - + + Always + + + PreserveNewest + - + + + + + @@ -69,7 +78,7 @@ - + ImportResources.resx True True @@ -77,7 +86,7 @@ - + Designer ImportResources.Designer.cs ResXFileCodeGenerator diff --git a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice.Security/BackOfficeCookieManagerTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice.Security/BackOfficeCookieManagerTests.cs index 83760bd177..d3424835e1 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice.Security/BackOfficeCookieManagerTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice.Security/BackOfficeCookieManagerTests.cs @@ -13,10 +13,10 @@ using Umbraco.Web; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.BackOffice.Security; -namespace Umbraco.Tests.Security +namespace Umbraco.Tests.Integration.Umbraco.Web.Backoffice.Security { [TestFixture] - public class BackOfficeCookieManagerTests + public class BackOfficeCookieManagerTests { [Test] public void ShouldAuthenticateRequest_When_Not_Configured() @@ -25,7 +25,7 @@ namespace Umbraco.Tests.Security var httpContextAccessor = testHelper.GetHttpContextAccessor(); var globalSettings = new GlobalSettings(); - + var runtime = Mock.Of(x => x.Level == RuntimeLevel.Install); var mgr = new BackOfficeCookieManager( Mock.Of(), @@ -74,7 +74,7 @@ namespace Umbraco.Tests.Security var globalSettings = new GlobalSettings(); var runtime = Mock.Of(x => x.Level == RuntimeLevel.Run); - + var mgr = new BackOfficeCookieManager( Mock.Of(), runtime, diff --git a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/BackOfficeLookupNormalizerTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/BackOfficeLookupNormalizerTests.cs index 0ba25e4a5b..532b488662 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/BackOfficeLookupNormalizerTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/BackOfficeLookupNormalizerTests.cs @@ -2,7 +2,7 @@ using NUnit.Framework; using Umbraco.Core.BackOffice; -namespace Umbraco.Tests.Security +namespace Umbraco.Tests.Integration.Umbraco.Web.Backoffice { public class BackOfficeLookupNormalizerTests { diff --git a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs index 75713c808b..f97a2db06d 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs @@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NUnit.Framework; @@ -25,7 +25,7 @@ using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.PropertyEditors; using DataType = Umbraco.Core.Models.DataType; -namespace Umbraco.Tests.Web.Validation +namespace Umbraco.Tests.Integration.Umbraco.Web.Backoffice.Filters { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, Mapper = true, WithApplication = true, Logger = UmbracoTestOptions.Logger.Console)] diff --git a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs index 58be305b91..450b3a341a 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs @@ -6,7 +6,7 @@ using Umbraco.Extensions; using Umbraco.Core.BackOffice; using Umbraco.Tests.Integration.Testing; -namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Extensions +namespace Umbraco.Tests.Integration.Umbraco.Web.BackOffice { [TestFixture] public class UmbracoBackOfficeServiceCollectionExtensionsTests : UmbracoIntegrationTest diff --git a/src/Umbraco.Tests.UnitTests/TestHelpers/BaseUsingSqlSyntax.cs b/src/Umbraco.Tests.UnitTests/TestHelpers/BaseUsingSqlSyntax.cs new file mode 100644 index 0000000000..749354ffde --- /dev/null +++ b/src/Umbraco.Tests.UnitTests/TestHelpers/BaseUsingSqlSyntax.cs @@ -0,0 +1,48 @@ +using System; +using Moq; +using NPoco; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Composing; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.Mappers; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Tests.TestHelpers +{ + [TestFixture] + public abstract class BaseUsingSqlSyntax + { + protected IMapperCollection Mappers { get; private set; } + + protected ISqlContext SqlContext { get; private set; } + + protected Sql Sql() + { + return NPoco.Sql.BuilderFor(SqlContext); + } + + [SetUp] + public virtual void Setup() + { + var container = TestHelper.GetRegister(); + var typeLoader = TestHelper.GetMockedTypeLoader(); + + var composition = new Composition(container, typeLoader, Mock.Of(), Mock.Of(), TestHelper.IOHelper, AppCaches.NoCache); + + composition.WithCollectionBuilder() + .AddCoreMappers(); + + composition.RegisterUnique(_ => SqlContext); + + var factory = composition.CreateFactory(); + var pocoMappers = new NPoco.MapperCollection { new PocoMapper() }; + var pocoDataFactory = new FluentPocoDataFactory((type, iPocoDataFactory) => new PocoDataBuilder(type, pocoMappers).Init()); + var sqlSyntax = new SqlServerSyntaxProvider(); + SqlContext = new SqlContext(sqlSyntax, DatabaseType.SqlServer2012, pocoDataFactory, new Lazy(() => factory.GetInstance())); + Mappers = factory.GetInstance(); + } + } +} diff --git a/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs index 9c619e05de..81accbf2ba 100644 --- a/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.IO; @@ -31,8 +32,10 @@ using Umbraco.Web.Routing; using File = System.IO.File; using Microsoft.Extensions.Options; using Umbraco.Core.Configuration.Models; +using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Web.Common.AspNetCore; using IHostingEnvironment = Umbraco.Core.Hosting.IHostingEnvironment; +using Umbraco.Infrastructure.Persistence.Mappers; namespace Umbraco.Tests.TestHelpers { @@ -78,6 +81,17 @@ namespace Umbraco.Tests.TestHelpers public static TypeLoader GetMockedTypeLoader() => _testHelperInternal.GetMockedTypeLoader(); + public static Lazy GetMockSqlContext() + { + var sqlContext = Mock.Of(); + var syntax = new SqlServerSyntaxProvider(); + Mock.Get(sqlContext).Setup(x => x.SqlSyntax).Returns(syntax); + return new Lazy(() => sqlContext); + } + + public static MapperConfigurationStore CreateMaps() + => new MapperConfigurationStore(); + //public static Configs GetConfigs() => _testHelperInternal.GetConfigs(); public static IBackOfficeInfo GetBackOfficeInfo() => _testHelperInternal.GetBackOfficeInfo(); @@ -256,51 +270,7 @@ namespace Umbraco.Tests.TestHelpers AssertAreEqual(property, expectedListEx[i], actualListEx[i], sorter, dateDeltaMilliseconds); } - public static void DeleteDirectory(string path) - { - Try(() => - { - if (Directory.Exists(path) == false) return; - foreach (var file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories)) - File.Delete(file); - }); - Try(() => - { - if (Directory.Exists(path) == false) return; - Directory.Delete(path, true); - }); - } - - public static void TryAssert(Action action, int maxTries = 5, int waitMilliseconds = 200) - { - Try(action, maxTries, waitMilliseconds); - } - - public static void Try(Action action, int maxTries = 5, int waitMilliseconds = 200) - { - Try(action, maxTries, waitMilliseconds); - } - - public static void Try(Action action, int maxTries = 5, int waitMilliseconds = 200) - where T : Exception - { - var tries = 0; - while (true) - { - try - { - action(); - break; - } - catch (T) - { - if (tries++ > maxTries) - throw; - Thread.Sleep(waitMilliseconds); - } - } - } public static IUmbracoVersion GetUmbracoVersion() => _testHelperInternal.GetUmbracoVersion(); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/IdentityExtensionsTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/IdentityExtensionsTests.cs index baf4a6f062..0c8b469f02 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/IdentityExtensionsTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/IdentityExtensionsTests.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Identity; using NUnit.Framework; using Umbraco.Extensions; -namespace Umbraco.Tests.Security +namespace Umbraco.Tests.UnitTests.Umbraco.Core.BackOffice { public class IdentityExtensionsTests { diff --git a/src/Umbraco.Tests/Cache/AppCacheTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/AppCacheTests.cs similarity index 95% rename from src/Umbraco.Tests/Cache/AppCacheTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/AppCacheTests.cs index 6b1c14d320..a30e254235 100644 --- a/src/Umbraco.Tests/Cache/AppCacheTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/AppCacheTests.cs @@ -1,14 +1,14 @@ using System; using System.Linq; -using System.Web.UI; using NUnit.Framework; using Umbraco.Core.Cache; -namespace Umbraco.Tests.Cache +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Cache { public abstract class AppCacheTests { internal abstract IAppCache AppCache { get; } + protected abstract int GetTotalItemCount { get; } [SetUp] @@ -66,10 +66,10 @@ namespace Umbraco.Tests.Cache try { result = AppCache.Get("Blah", () => - { - counter++; - throw new Exception("Do not cache this"); - }); + { + counter++; + throw new Exception("Do not cache this"); + }); } catch (Exception){} @@ -85,16 +85,16 @@ namespace Umbraco.Tests.Cache object result; result = AppCache.Get("Blah", () => - { - counter++; - return ""; - }); + { + counter++; + return ""; + }); result = AppCache.Get("Blah", () => - { - counter++; - return ""; - }); + { + counter++; + return ""; + }); Assert.AreEqual(1, counter); @@ -257,5 +257,9 @@ namespace Umbraco.Tests.Cache private class MacroCacheContent { } + + private class LiteralControl + { + } } } diff --git a/src/Umbraco.Tests/Cache/DeepCloneAppCacheTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/DeepCloneAppCacheTests.cs similarity index 84% rename from src/Umbraco.Tests/Cache/DeepCloneAppCacheTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/DeepCloneAppCacheTests.cs index f7b39590f2..cbcd164b62 100644 --- a/src/Umbraco.Tests/Cache/DeepCloneAppCacheTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/DeepCloneAppCacheTests.cs @@ -1,22 +1,14 @@ using System; using System.Diagnostics; using System.Linq; -using System.Reflection; -using System.Web; -using Moq; using NUnit.Framework; -using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Collections; -using Umbraco.Core.Composing; -using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Tests.Common; -using Umbraco.Tests.TestHelpers; -using Umbraco.Web.Cache; -namespace Umbraco.Tests.Cache +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Cache { [TestFixture] public class DeepCloneAppCacheTests : RuntimeAppCacheTests @@ -41,12 +33,14 @@ namespace Umbraco.Tests.Cache [Test] public void Clones_List() { - var original = new DeepCloneableList(ListCloneBehavior.Always); - original.Add(new TestClone()); - original.Add(new TestClone()); - original.Add(new TestClone()); + var original = new DeepCloneableList(ListCloneBehavior.Always) + { + new TestClone(), + new TestClone(), + new TestClone() + }; - var val = _provider.GetCacheItem>("test", () => original); + var val = _provider.GetCacheItem("test", () => original); Assert.AreEqual(original.Count, val.Count); foreach (var item in val) @@ -64,7 +58,7 @@ namespace Umbraco.Tests.Cache }; Assert.IsTrue(original.IsDirty()); - var val = _provider.GetCacheItem("test", () => original); + var val = _provider.GetCacheItem("test", () => original); Assert.AreNotEqual(original.CloneId, val.CloneId); Assert.IsFalse(val.IsDirty()); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/DictionaryAppCacheTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/DictionaryAppCacheTests.cs new file mode 100644 index 0000000000..91d71d3144 --- /dev/null +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/DictionaryAppCacheTests.cs @@ -0,0 +1,21 @@ +using NUnit.Framework; +using Umbraco.Core.Cache; + +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Cache +{ + [TestFixture] + public class DictionaryAppCacheTests : AppCacheTests + { + private DictionaryAppCache _appCache; + + public override void Setup() + { + base.Setup(); + _appCache = new DictionaryAppCache(); + } + + internal override IAppCache AppCache => _appCache; + + protected override int GetTotalItemCount => _appCache.Count; + } +} diff --git a/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/DistributedCache/DistributedCacheTests.cs similarity index 90% rename from src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/DistributedCache/DistributedCacheTests.cs index 6043e7b0d6..0d5b1edb31 100644 --- a/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/DistributedCache/DistributedCacheTests.cs @@ -3,10 +3,9 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; using Umbraco.Core.Cache; -using Umbraco.Web.Composing; using Umbraco.Core.Sync; -namespace Umbraco.Tests.Cache.DistributedCache +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Cache.DistributedCache { /// /// Ensures that calls to DistributedCache methods carry through to the IServerMessenger correctly @@ -14,7 +13,7 @@ namespace Umbraco.Tests.Cache.DistributedCache [TestFixture] public class DistributedCacheTests { - private Umbraco.Web.Cache.DistributedCache _distributedCache; + private global::Umbraco.Web.Cache.DistributedCache _distributedCache; private IServerRegistrar ServerRegistrar { get; set; } private TestServerMessenger ServerMessenger { get; set; } @@ -30,13 +29,7 @@ namespace Umbraco.Tests.Cache.DistributedCache new TestCacheRefresher() }); - _distributedCache = new Umbraco.Web.Cache.DistributedCache(ServerMessenger, cacheRefresherCollection); - } - - [TearDown] - public void Teardown() - { - Current.Reset(); + _distributedCache = new global::Umbraco.Web.Cache.DistributedCache(ServerMessenger, cacheRefresherCollection); } [Test] @@ -46,6 +39,7 @@ namespace Umbraco.Tests.Cache.DistributedCache { _distributedCache.Refresh(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), i); } + Assert.AreEqual(10, ServerMessenger.IntIdsRefreshed.Count); } @@ -59,6 +53,7 @@ namespace Umbraco.Tests.Cache.DistributedCache x => x.Id, new TestObjectWithId{Id = i}); } + Assert.AreEqual(10, ServerMessenger.IntIdsRefreshed.Count); } @@ -69,6 +64,7 @@ namespace Umbraco.Tests.Cache.DistributedCache { _distributedCache.Refresh(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), Guid.NewGuid()); } + Assert.AreEqual(11, ServerMessenger.GuidIdsRefreshed.Count); } @@ -79,6 +75,7 @@ namespace Umbraco.Tests.Cache.DistributedCache { _distributedCache.Remove(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), i); } + Assert.AreEqual(12, ServerMessenger.IntIdsRemoved.Count); } @@ -89,10 +86,11 @@ namespace Umbraco.Tests.Cache.DistributedCache { _distributedCache.RefreshAll(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73")); } + Assert.AreEqual(13, ServerMessenger.CountOfFullRefreshes); } - #region internal test classes + #region Internal test classes internal class TestObjectWithId { @@ -107,17 +105,13 @@ namespace Umbraco.Tests.Cache.DistributedCache public string Name => "Test Cache Refresher"; - public void RefreshAll() - { } + public void RefreshAll() { } - public void Refresh(int id) - { } + public void Refresh(int id) { } - public void Remove(int id) - { } + public void Remove(int id) { } - public void Refresh(Guid id) - { } + public void Refresh(Guid id) { } } internal class TestServerMessenger : IServerMessenger @@ -192,7 +186,6 @@ namespace Umbraco.Tests.Cache.DistributedCache { throw new NotImplementedException(); } - } public class TestServerAddress : IServerAddress @@ -201,6 +194,7 @@ namespace Umbraco.Tests.Cache.DistributedCache { ServerAddress = address; } + public string ServerAddress { get; private set; } } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/HttpRequestAppCacheTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/HttpRequestAppCacheTests.cs new file mode 100644 index 0000000000..02a10fcff4 --- /dev/null +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/HttpRequestAppCacheTests.cs @@ -0,0 +1,24 @@ +using Microsoft.AspNetCore.Http; +using NUnit.Framework; +using Umbraco.Core.Cache; + +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Cache +{ + [TestFixture] + public class HttpRequestAppCacheTests : AppCacheTests + { + private HttpRequestAppCache _appCache; + private HttpContext _httpContext; + + public override void Setup() + { + base.Setup(); + _httpContext = new DefaultHttpContext();; + _appCache = new HttpRequestAppCache(() => _httpContext.Items); + } + + internal override IAppCache AppCache => _appCache; + + protected override int GetTotalItemCount => _httpContext.Items.Count; + } +} diff --git a/src/Umbraco.Tests/Cache/ObjectAppCacheTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/ObjectAppCacheTests.cs similarity index 91% rename from src/Umbraco.Tests/Cache/ObjectAppCacheTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/ObjectAppCacheTests.cs index 3172738bf7..51639d7c49 100644 --- a/src/Umbraco.Tests/Cache/ObjectAppCacheTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/ObjectAppCacheTests.cs @@ -1,9 +1,8 @@ using System.Linq; using NUnit.Framework; using Umbraco.Core.Cache; -using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Cache +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Cache { [TestFixture] public class ObjectAppCacheTests : RuntimeAppCacheTests diff --git a/src/Umbraco.Tests/Cache/RuntimeAppCacheTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/RuntimeAppCacheTests.cs similarity index 94% rename from src/Umbraco.Tests/Cache/RuntimeAppCacheTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/RuntimeAppCacheTests.cs index 1beeae74db..33a71b1044 100644 --- a/src/Umbraco.Tests/Cache/RuntimeAppCacheTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Cache/RuntimeAppCacheTests.cs @@ -3,7 +3,7 @@ using System.Threading; using NUnit.Framework; using Umbraco.Core.Cache; -namespace Umbraco.Tests.Cache +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Cache { public abstract class RuntimeAppCacheTests : AppCacheTests { diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs index 47a1b58abb..7b9c043be9 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs @@ -19,7 +19,7 @@ using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Scoping; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Components +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Components { [TestFixture] public class ComponentTests @@ -176,7 +176,7 @@ namespace Umbraco.Tests.Components } catch (Exception e) { - Assert.AreEqual("Broken composer dependency: Umbraco.Tests.Components.ComponentTests+Composer2 -> Umbraco.Tests.Components.ComponentTests+Composer4.", e.Message); + Assert.AreEqual("Broken composer dependency: Umbraco.Tests.UnitTests.Umbraco.Core.Components.ComponentTests+Composer2 -> Umbraco.Tests.UnitTests.Umbraco.Core.Components.ComponentTests+Composer4.", e.Message); } } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CollectionBuildersTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CollectionBuildersTests.cs index 266aa64803..e046c15cb4 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CollectionBuildersTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CollectionBuildersTests.cs @@ -7,10 +7,9 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Logging; -using Umbraco.Tests.Components; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Composing +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { [TestFixture] public class CollectionBuildersTests @@ -28,7 +27,7 @@ namespace Umbraco.Tests.Composing // factoryMock.Setup(x => x.GetInstance(typeof(Resolved3))).Returns(new Resolved3()); // factoryMock.Setup(x => x.GetInstance(typeof(Resolved4))).Returns(new Resolved4()); - + var register = TestHelper.GetRegister(); _composition = new Composition(register, TestHelper.GetMockedTypeLoader(), Mock.Of(), Mock.Of(), TestHelper.IOHelper, AppCaches.NoCache); } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ComposingTestBase.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ComposingTestBase.cs index f15d28bd37..fb6e95c875 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ComposingTestBase.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ComposingTestBase.cs @@ -9,7 +9,7 @@ using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Composing +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { public abstract class ComposingTestBase { @@ -26,7 +26,7 @@ namespace Umbraco.Tests.Composing var ioHelper = TestHelper.IOHelper; TypeLoader = new TypeLoader(typeFinder, NoAppCache.Instance, new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), Mock.Of>(), ProfilingLogger, false, AssembliesToScan); } - + protected virtual IEnumerable AssembliesToScan => new[] { diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CompositionTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CompositionTests.cs index a078a9bac5..1401d7c66f 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CompositionTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CompositionTests.cs @@ -1,59 +1,10 @@ -using System; -using System.IO; -using Microsoft.Extensions.Logging; -using Moq; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Composing; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using Umbraco.Tests.TestHelpers; +using NUnit.Framework; -namespace Umbraco.Tests.Composing +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { [TestFixture] public class CompositionTests { - [Test] - public void FactoryIsResolvable() - { - Func factoryFactory = null; - var mockedRegister = Mock.Of(); - var mockedFactory = Mock.Of(); - - // the mocked register creates the mocked factory - Mock.Get(mockedRegister) - .Setup(x => x.CreateFactory()) - .Returns(mockedFactory); - - // the mocked register can register a factory factory - Mock.Get(mockedRegister) - .Setup(x => x.Register(It.IsAny>(), Lifetime.Singleton)) - .Callback, Lifetime>((ff, lt) => factoryFactory = ff); - - // the mocked factory can invoke the factory factory - Mock.Get(mockedFactory) - .Setup(x => x.GetInstance(typeof(IFactory))) - .Returns(() => factoryFactory?.Invoke(mockedFactory)); - - var logger = new ProfilingLogger(Mock.Of(), Mock.Of()); - var typeFinder = TestHelper.GetTypeFinder(); - var ioHelper = TestHelper.IOHelper; - var typeLoader = new TypeLoader(typeFinder, Mock.Of(), new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), Mock.Of>(), logger); - var composition = new Composition(mockedRegister, typeLoader, logger, Mock.Of(), TestHelper.IOHelper, AppCaches.NoCache); - - // create the factory, ensure it is the mocked factory - var factory = composition.CreateFactory(); - Assert.AreSame(mockedFactory, factory); - - // ensure we can get an IFactory instance, - // meaning that it has been properly registered - - var resolved = factory.GetInstance(); - Assert.IsNotNull(resolved); - Assert.AreSame(factory, resolved); - } } } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ContainerConformingTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ContainerConformingTests.cs index 6819823dd5..a091a22199 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ContainerConformingTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ContainerConformingTests.cs @@ -6,7 +6,7 @@ using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Composing +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { [TestFixture] public class ContainerConformingTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/LazyCollectionBuilderTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/LazyCollectionBuilderTests.cs index 7f0af94d1e..e1a3f75ba2 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/LazyCollectionBuilderTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/LazyCollectionBuilderTests.cs @@ -7,10 +7,9 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Logging; -using Umbraco.Tests.Components; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Composing +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { [TestFixture] public class LazyCollectionBuilderTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/PackageActionCollectionTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/PackageActionCollectionTests.cs index 4d1db92251..a144f9340a 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/PackageActionCollectionTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/PackageActionCollectionTests.cs @@ -9,10 +9,9 @@ using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core.PackageActions; -using Umbraco.Tests.Components; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Composing +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { [TestFixture] public class PackageActionCollectionTests : ComposingTestBase diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeFinderTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeFinderTests.cs index b8e391a072..9ef2cf5ae0 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeFinderTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeFinderTests.cs @@ -9,7 +9,7 @@ using Umbraco.Core.Logging; using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Web.BackOffice.Trees; -namespace Umbraco.Tests.Composing +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { /// diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeHelperTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeHelperTests.cs index fb7f158804..c78992d68c 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeHelperTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeHelperTests.cs @@ -9,7 +9,7 @@ using System.Reflection; using NUnit.Framework; using Umbraco.Core.Composing; -namespace Umbraco.Tests.Composing +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { /// /// Tests for TypeHelper @@ -45,14 +45,14 @@ namespace Umbraco.Tests.Composing typeof (OdbcCommand), typeof (SqlCommand)); Assert.IsFalse(t1.Success); - + var t2 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand), typeof (OdbcCommand), typeof (SqlCommand), typeof (Component)); Assert.IsTrue(t2.Success); Assert.AreEqual(typeof(Component), t2.Result); - + var t3 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand), typeof (OdbcCommand), typeof (SqlCommand), @@ -60,7 +60,7 @@ namespace Umbraco.Tests.Composing typeof (Component).BaseType); Assert.IsTrue(t3.Success); Assert.AreEqual(typeof(MarshalByRefObject), t3.Result); - + var t4 = TypeHelper.GetLowestBaseType(typeof(OleDbCommand), typeof(OdbcCommand), typeof(SqlCommand), @@ -68,17 +68,17 @@ namespace Umbraco.Tests.Composing typeof(Component).BaseType, typeof(int)); Assert.IsFalse(t4.Success); - + var t5 = TypeHelper.GetLowestBaseType(typeof(PropertyAliasDto)); Assert.IsTrue(t5.Success); Assert.AreEqual(typeof(PropertyAliasDto), t5.Result); - + //var t6 = TypeHelper.GetLowestBaseType(typeof (IApplicationEventHandler), // typeof (SchedulerComponent), // typeof(CacheRefresherComponent)); //Assert.IsTrue(t6.Success); //Assert.AreEqual(typeof(IApplicationEventHandler), t6.Result); - + } [Test] diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderExtensions.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderExtensions.cs index 12a5c01d81..6bab57ee41 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderExtensions.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderExtensions.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using Umbraco.Core.Composing; -namespace Umbraco.Tests.Composing +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { /// /// Used for PluginTypeResolverTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderTests.cs index 64de9a70c9..7d22b0c958 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderTests.cs @@ -15,7 +15,7 @@ using Umbraco.Tests.TestHelpers; using Umbraco.Web; using Umbraco.Web.PropertyEditors; -namespace Umbraco.Tests.Composing +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { [TestFixture] public class TypeLoaderTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Configurations/GlobalSettingsTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Configurations/GlobalSettingsTests.cs index be040c221b..3b0d13c584 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Configurations/GlobalSettingsTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Configurations/GlobalSettingsTests.cs @@ -7,10 +7,10 @@ using Umbraco.Tests.UnitTests.AutoFixture; using Umbraco.Web.Common.AspNetCore; -namespace Umbraco.Tests.Configurations +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Configurations { [TestFixture] - public class GlobalSettingsTests + public class GlobalSettingsTests { [InlineAutoMoqData("~/umbraco", "/", "umbraco")] [InlineAutoMoqData("~/umbraco", "/MyVirtualDir", "umbraco")] diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/CallContextTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/CallContextTests.cs index b97a87542c..dec0ff9a29 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/CallContextTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/CallContextTests.cs @@ -3,7 +3,7 @@ using System; using Umbraco.Core; using Umbraco.Core.Scoping; -namespace Umbraco.Tests.CoreThings +namespace Umbraco.Tests.UnitTests.Umbraco.Core.CoreThings { [TestFixture] public class CallContextTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/ObjectExtensionsTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/ObjectExtensionsTests.cs index 3b09de2d0b..f3fa46ef5e 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/ObjectExtensionsTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/ObjectExtensionsTests.cs @@ -8,7 +8,7 @@ using Umbraco.Core; using Umbraco.Core.PropertyEditors; using Umbraco.Tests.TestHelpers.Entities; -namespace Umbraco.Tests.CoreThings +namespace Umbraco.Tests.UnitTests.Umbraco.Core.CoreThings { [TestFixture] public class ObjectExtensionsTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/TryConvertToTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/TryConvertToTests.cs index c5c027ac65..a0dddd8b5e 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/TryConvertToTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/TryConvertToTests.cs @@ -7,7 +7,7 @@ using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Strings; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.CoreThings +namespace Umbraco.Tests.UnitTests.Umbraco.Core.CoreThings { [TestFixture] public class TryConvertToTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/UdiTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/UdiTests.cs index 2ab39f3664..e8fe9d5415 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/UdiTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreThings/UdiTests.cs @@ -8,7 +8,7 @@ using Umbraco.Core; using Umbraco.Core.Deploy; using Umbraco.Core.Serialization; -namespace Umbraco.Tests.CoreThings +namespace Umbraco.Tests.UnitTests.Umbraco.Core.CoreThings { [TestFixture] public class UdiTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/FrameworkXmlTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/FrameworkXmlTests.cs index ec1ccb3c00..42e3aa7357 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/FrameworkXmlTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/FrameworkXmlTests.cs @@ -7,7 +7,7 @@ using System.Xml.XPath; using NUnit.Framework; -namespace Umbraco.Tests.CoreXml +namespace Umbraco.Tests.UnitTests.Umbraco.Core.CoreXml { [TestFixture] public class FrameworkXmlTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/NavigableNavigatorTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/NavigableNavigatorTests.cs index c0d5d9af6d..c5629aca10 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/NavigableNavigatorTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/NavigableNavigatorTests.cs @@ -10,9 +10,8 @@ using System.Xml.Xsl; using Umbraco.Core.Xml; using Umbraco.Core.Xml.XPath; using NUnit.Framework; -using Umbraco.Tests.Testing; -namespace Umbraco.Tests.CoreXml +namespace Umbraco.Tests.UnitTests.Umbraco.Core.CoreXml { [TestFixture] public class NavigableNavigatorTests @@ -76,7 +75,6 @@ namespace Umbraco.Tests.CoreXml { // in non-native we can't have Value dump everything, else // we'd dump the entire database? Makes not much sense. - Assert.AreEqual(native ? "\n blah\n blah\n bam\n " : string.Empty, nav.Value.Lf()); // !! Assert.IsTrue(nav.MoveToFirstChild()); Assert.AreEqual("root", nav.Name); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/RenamedRootNavigatorTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/RenamedRootNavigatorTests.cs index bdc4e710c0..5afc68955d 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/RenamedRootNavigatorTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/RenamedRootNavigatorTests.cs @@ -1,9 +1,10 @@ -using System.Xml; +using System.Runtime.InteropServices; +using System.Xml; using System.Xml.XPath; using NUnit.Framework; using Umbraco.Core.Xml.XPath; -namespace Umbraco.Tests.CoreXml +namespace Umbraco.Tests.UnitTests.Umbraco.Core.CoreXml { [TestFixture] public class RenamedRootNavigatorTests @@ -18,10 +19,10 @@ namespace Umbraco.Tests.CoreXml "); var nav = doc.CreateNavigator(); var xml = nav.OuterXml; - Assert.AreEqual(@" + Assert.AreEqual(EnsureNativeLineEndings(@" -".CrLf(), xml); +"), xml); } [Test] @@ -34,10 +35,10 @@ namespace Umbraco.Tests.CoreXml "); var nav = doc.CreateNavigator(); var xml = nav.OuterXml; - Assert.AreEqual(@" + Assert.AreEqual(EnsureNativeLineEndings(@" -".CrLf(), xml); +"), xml); } [Test] @@ -50,10 +51,16 @@ namespace Umbraco.Tests.CoreXml "); var nav = new RenamedRootNavigator(doc.CreateNavigator(), "test"); var xml = nav.OuterXml; - Assert.AreEqual(@" + Assert.AreEqual(EnsureNativeLineEndings(@" -".CrLf(), xml); +"), xml); + } + + private string EnsureNativeLineEndings(string text) + { + var useCrLf = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + return useCrLf ? text.CrLf() : text.Lf(); } [Test] @@ -66,10 +73,10 @@ namespace Umbraco.Tests.CoreXml "); var nav = new RenamedRootNavigator(doc.CreateNavigator(), "test"); var xml = nav.OuterXml; - Assert.AreEqual(@" + Assert.AreEqual(EnsureNativeLineEndings(@" -".CrLf(), xml); +"), xml); } [Test] diff --git a/src/Umbraco.Tests/IO/AbstractFileSystemTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/IO/AbstractFileSystemTests.cs similarity index 98% rename from src/Umbraco.Tests/IO/AbstractFileSystemTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/IO/AbstractFileSystemTests.cs index 2ca5d0bdc2..3502c74494 100644 --- a/src/Umbraco.Tests/IO/AbstractFileSystemTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/IO/AbstractFileSystemTests.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; @@ -7,7 +6,7 @@ using System.Threading; using NUnit.Framework; using Umbraco.Core.IO; -namespace Umbraco.Tests.IO +namespace Umbraco.Tests.UnitTests.Umbraco.Core.IO { [TestFixture] [Apartment(ApartmentState.STA)] @@ -179,7 +178,7 @@ namespace Umbraco.Tests.IO protected Stream CreateStream(string contents = null) { - if(string.IsNullOrEmpty(contents)) + if (string.IsNullOrEmpty(contents)) contents = "test"; var bytes = Encoding.UTF8.GetBytes(contents); diff --git a/src/Umbraco.Tests/IO/PhysicalFileSystemTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/IO/PhysicalFileSystemTests.cs similarity index 95% rename from src/Umbraco.Tests/IO/PhysicalFileSystemTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/IO/PhysicalFileSystemTests.cs index bd26bbcc66..7b98d77f58 100644 --- a/src/Umbraco.Tests/IO/PhysicalFileSystemTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/IO/PhysicalFileSystemTests.cs @@ -8,8 +8,7 @@ using NUnit.Framework; using Umbraco.Core.IO; using Umbraco.Tests.TestHelpers; - -namespace Umbraco.Tests.IO +namespace Umbraco.Tests.UnitTests.Umbraco.Core.IO { [TestFixture] [Apartment(ApartmentState.STA)] @@ -36,6 +35,7 @@ namespace Umbraco.Tests.IO { File.Delete(f); } + Directory.Delete(path, true); } @@ -67,8 +67,8 @@ namespace Umbraco.Tests.IO Assert.Throws(() => { - using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) - _fileSystem.AddFile(path + "f3.txt", ms); + using var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")); + _fileSystem.AddFile(path + "f3.txt", ms); }); } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Manifest/ManifestContentAppTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Manifest/ManifestContentAppTests.cs index 5265349e69..92876f1b98 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Manifest/ManifestContentAppTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Manifest/ManifestContentAppTests.cs @@ -10,7 +10,7 @@ using Umbraco.Core.Models.Membership; using Umbraco.Tests.TestHelpers; using Umbraco.Web.Composing; -namespace Umbraco.Tests.Manifest +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Manifest { [TestFixture] public class ManifestContentAppTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Manifest/ManifestParserTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Manifest/ManifestParserTests.cs index 1e26082453..4bc531944e 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Manifest/ManifestParserTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Manifest/ManifestParserTests.cs @@ -19,7 +19,7 @@ using Umbraco.Core.Serialization; using Umbraco.Core.Strings; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Manifest +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Manifest { [TestFixture] public class ManifestParserTests diff --git a/src/Umbraco.Tests/Models/Collections/Item.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/Item.cs similarity index 99% rename from src/Umbraco.Tests/Models/Collections/Item.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/Item.cs index 38cf8ecb4b..8593d01946 100644 --- a/src/Umbraco.Tests/Models/Collections/Item.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/Item.cs @@ -7,7 +7,7 @@ using System.Runtime.Serialization; using Umbraco.Core; using Umbraco.Core.Models.Entities; -namespace Umbraco.Tests.Models.Collections +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models.Collections { public abstract class Item : IEntity, ICanBeDirty { diff --git a/src/Umbraco.Tests/Models/Collections/OrderItem.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/OrderItem.cs similarity index 78% rename from src/Umbraco.Tests/Models/Collections/OrderItem.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/OrderItem.cs index 8d010495ac..60c57dd1e5 100644 --- a/src/Umbraco.Tests/Models/Collections/OrderItem.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/OrderItem.cs @@ -1,7 +1,7 @@ using System; -namespace Umbraco.Tests.Models.Collections -{ +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models.Collections +{ public class OrderItem : Item { public readonly int PartNumber; @@ -13,10 +13,10 @@ namespace Umbraco.Tests.Models.Collections public OrderItem(int partNumber, string description, int quantity, double unitPrice) { - this.PartNumber = partNumber; - this.Description = description; - this.Quantity = quantity; - this.UnitPrice = unitPrice; + PartNumber = partNumber; + Description = description; + Quantity = quantity; + UnitPrice = unitPrice; } public int Quantity @@ -33,7 +33,7 @@ namespace Umbraco.Tests.Models.Collections public override string ToString() { - return String.Format( + return string.Format( "{0,9} {1,6} {2,-12} at {3,8:#,###.00} = {4,10:###,###.00}", PartNumber, _quantity, Description, UnitPrice, UnitPrice * _quantity); diff --git a/src/Umbraco.Tests/Models/Collections/PropertyCollectionTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/PropertyCollectionTests.cs similarity index 77% rename from src/Umbraco.Tests/Models/Collections/PropertyCollectionTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/PropertyCollectionTests.cs index e36e89e183..6c76cc29a2 100644 --- a/src/Umbraco.Tests/Models/Collections/PropertyCollectionTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/PropertyCollectionTests.cs @@ -3,22 +3,22 @@ using System.Linq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models; +using Umbraco.Tests.Common.Builders; using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; -using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Models.Collections +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models.Collections { [TestFixture] - public class PropertyCollectionTests : UmbracoTestBase + public class PropertyCollectionTests { [Test] public void Property_Adds_Case_Insensitive_Compare() { - var collection = new PropertyCollection(); - - collection.Add(new Property(new PropertyType(TestHelper.ShortStringHelper, "propEditor", ValueStorageType.Nvarchar, "test"))); - collection.Add(new Property(new PropertyType(TestHelper.ShortStringHelper, "propEditor", ValueStorageType.Nvarchar, "Test"))); + var collection = new PropertyCollection + { + new Property(new PropertyType(TestHelper.ShortStringHelper, "propEditor", ValueStorageType.Nvarchar, "test")), + new Property(new PropertyType(TestHelper.ShortStringHelper, "propEditor", ValueStorageType.Nvarchar, "Test")) + }; Assert.AreEqual(1, collection.Count); } @@ -26,9 +26,10 @@ namespace Umbraco.Tests.Models.Collections [Test] public void Property_Contains_Case_Insensitive_Compare() { - var collection = new PropertyCollection(); - - collection.Add(new Property(new PropertyType(TestHelper.ShortStringHelper, "propEditor", ValueStorageType.Nvarchar, "test"))); + var collection = new PropertyCollection + { + new Property(new PropertyType(TestHelper.ShortStringHelper, "propEditor", ValueStorageType.Nvarchar, "test")) + }; Assert.IsTrue(collection.Contains("Test")); } @@ -79,7 +80,7 @@ namespace Umbraco.Tests.Models.Collections [Test] public void PropertyGroups_Collection_FirstOrDefault_Returns_Null() { - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Assert.That(contentType.PropertyGroups, Is.Not.Null); Assert.That(contentType.PropertyGroups.FirstOrDefault(x => x.Name.InvariantEquals("Content")) == null, Is.False); diff --git a/src/Umbraco.Tests/Models/Collections/SimpleOrder.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/SimpleOrder.cs similarity index 93% rename from src/Umbraco.Tests/Models/Collections/SimpleOrder.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/SimpleOrder.cs index 4b52289e2a..d8c47f45f4 100644 --- a/src/Umbraco.Tests/Models/Collections/SimpleOrder.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/Collections/SimpleOrder.cs @@ -2,9 +2,8 @@ using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Linq; -using Umbraco.Core; -namespace Umbraco.Tests.Models.Collections +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models.Collections { public class SimpleOrder : KeyedCollection, INotifyCollectionChanged { @@ -73,10 +72,7 @@ namespace Umbraco.Tests.Models.Collections protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args) { - if (CollectionChanged != null) - { - CollectionChanged(this, args); - } + CollectionChanged?.Invoke(this, args); } } } diff --git a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentExtensionsTests.cs similarity index 62% rename from src/Umbraco.Tests/Models/ContentExtensionsTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentExtensionsTests.cs index ae59e377d0..333ec11720 100644 --- a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentExtensionsTests.cs @@ -1,58 +1,24 @@ using System; using System.Linq; -using Microsoft.Extensions.Logging.Abstractions; using Moq; using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Composing.CompositionExtensions; -using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Models; -using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; -using Umbraco.Core.Services.Implement; -using Umbraco.Tests.TestHelpers.Entities; -using Umbraco.Tests.Testing; -using Umbraco.Web.PropertyEditors; +using Umbraco.Tests.Common.Builders; -namespace Umbraco.Tests.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] - public class ContentExtensionsTests : UmbracoTestBase + public class ContentExtensionsTests { - private IContentTypeService _contentTypeService; - - protected override void Compose() - { - base.Compose(); - - Composition.ComposeFileSystems(); - - Composition.Register(_ => Mock.Of()); - - // all this is required so we can validate properties... - var editor = new TextboxPropertyEditor(NullLoggerFactory.Instance, Mock.Of(), Mock.Of(), IOHelper, ShortStringHelper, LocalizedTextService) { Alias = "test" }; - Composition.Register(_ => new DataEditorCollection(new[] { editor })); - Composition.Register(); - var dataType = Mock.Of(); - Mock.Get(dataType).Setup(x => x.Configuration).Returns(() => new object()); - var dataTypeService = Mock.Of(); - Mock.Get(dataTypeService) - .Setup(x => x.GetDataType(It.IsAny())) - .Returns(() => dataType); - - _contentTypeService = Mock.Of(); - var mediaTypeService = Mock.Of(); - var memberTypeService = Mock.Of(); - Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); - } - [Test] public void DirtyProperty_Reset_Clears_SavedPublishedState() { - var contentType = MockedContentTypes.CreateTextPageContentType(); - Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var contentTypeService = Mock.Of(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); + Mock.Get(contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); content.PublishedState = PublishedState.Publishing; Assert.IsFalse(content.Published); @@ -64,10 +30,11 @@ namespace Umbraco.Tests.Models [Test] public void DirtyProperty_OnlyIfActuallyChanged_Content() { - var contentType = MockedContentTypes.CreateTextPageContentType(); - Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var contentTypeService = Mock.Of(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); + Mock.Get(contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // if you assign a content property with its value it is not dirty // if you assign it with another value then back, it is dirty @@ -88,10 +55,11 @@ namespace Umbraco.Tests.Models [Test] public void DirtyProperty_OnlyIfActuallyChanged_User() { - var contentType = MockedContentTypes.CreateTextPageContentType(); - Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var contentTypeService = Mock.Of(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); + Mock.Get(contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); var prop = content.Properties.First(); // if you assign a user property with its value it is not dirty @@ -114,10 +82,11 @@ namespace Umbraco.Tests.Models [Test] public void DirtyProperty_UpdateDate() { - var contentType = MockedContentTypes.CreateTextPageContentType(); - Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var contentTypeService = Mock.Of(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); + Mock.Get(contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); var prop = content.Properties.First(); content.ResetDirtyProperties(false); @@ -139,10 +108,11 @@ namespace Umbraco.Tests.Models [Test] public void DirtyProperty_WasDirty_ContentProperty() { - var contentType = MockedContentTypes.CreateTextPageContentType(); - Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var contentTypeService = Mock.Of(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); + Mock.Get(contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(false); Assert.IsFalse(content.IsDirty()); Assert.IsFalse(content.WasDirty()); @@ -168,10 +138,11 @@ namespace Umbraco.Tests.Models [Test] public void DirtyProperty_WasDirty_ContentSortOrder() { - var contentType = MockedContentTypes.CreateTextPageContentType(); - Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var contentTypeService = Mock.Of(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); + Mock.Get(contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(false); Assert.IsFalse(content.IsDirty()); Assert.IsFalse(content.WasDirty()); @@ -197,10 +168,11 @@ namespace Umbraco.Tests.Models [Test] public void DirtyProperty_WasDirty_UserProperty() { - var contentType = MockedContentTypes.CreateTextPageContentType(); - Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var contentTypeService = Mock.Of(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); + Mock.Get(contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); var prop = content.Properties.First(); content.ResetDirtyProperties(false); Assert.IsFalse(content.IsDirty()); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/ContentScheduleTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentScheduleTests.cs similarity index 98% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/ContentScheduleTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentScheduleTests.cs index 83dbfa08a5..36bf5418b3 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/ContentScheduleTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentScheduleTests.cs @@ -3,7 +3,7 @@ using System.Linq; using NUnit.Framework; using Umbraco.Core.Models; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class ContentScheduleTests diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentTests.cs similarity index 69% rename from src/Umbraco.Tests/Models/ContentTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentTests.cs index 8fb3f60cc8..e6adc2eb5e 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentTests.cs @@ -7,62 +7,40 @@ using System.Threading; using Microsoft.Extensions.Logging.Abstractions; using Moq; using Newtonsoft.Json; -using Umbraco.Core; using NUnit.Framework; +using Umbraco.Core; using Umbraco.Core.Cache; -using Umbraco.Core.Composing.CompositionExtensions; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; -using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; -using Umbraco.Core.Services.Implement; -using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Tests.Common.Builders; +using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Tests.Testing; -using Umbraco.Web.PropertyEditors; -namespace Umbraco.Tests.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] - public class ContentTests : UmbracoTestBase + public class ContentTests { - private IContentTypeService _contentTypeService; - - protected override void Compose() - { - base.Compose(); - - Composition.ComposeFileSystems(); - - Composition.Register(_ => Mock.Of()); - - // all this is required so we can validate properties... - var editor = new TextboxPropertyEditor(NullLoggerFactory.Instance, Mock.Of(), Mock.Of(), IOHelper, ShortStringHelper, LocalizedTextService) { Alias = "test" }; - Composition.Register(_ => new DataEditorCollection(new [] { editor })); - Composition.Register(); - var dataType = Mock.Of(); - Mock.Get(dataType).Setup(x => x.Configuration).Returns(() => new object()); - var dataTypeService = Mock.Of(); - Mock.Get(dataTypeService) - .Setup(x => x.GetDataType(It.IsAny())) - .Returns(() => dataType); - - _contentTypeService = Mock.Of(); - var mediaTypeService = Mock.Of(); - var memberTypeService = Mock.Of(); - Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); - - } + private IContentTypeService _contentTypeService = Mock.Of(); [Test] public void Variant_Culture_Names_Track_Dirty_Changes() { - var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" }; - contentType.Variations = ContentVariation.Culture; + var contentType = new ContentTypeBuilder() + .WithAlias("contentType") + .WithContentVariation(ContentVariation.Culture) + .Build(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; + var content = new ContentBuilder() + .WithId(1) + .WithVersionId(1) + .WithName("content") + .WithContentType(contentType) + .Build(); const string langFr = "fr-FR"; @@ -88,13 +66,19 @@ namespace Umbraco.Tests.Models [Test] public void Variant_Published_Culture_Names_Track_Dirty_Changes() { - var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" }; - var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; + var contentType = new ContentTypeBuilder() + .WithAlias("contentType") + .WithContentVariation(ContentVariation.Culture) + .Build(); + var content = new ContentBuilder() + .WithId(1) + .WithVersionId(1) + .WithName("content") + .WithContentType(contentType) + .Build(); const string langFr = "fr-FR"; - contentType.Variations = ContentVariation.Culture; - content.ChangeContentType(contentType); Assert.IsFalse(content.IsPropertyDirty("PublishCultureInfos")); //hasn't been changed @@ -121,18 +105,25 @@ namespace Umbraco.Tests.Models [Test] public void Get_Non_Grouped_Properties() { - var contentType = MockedContentTypes.CreateSimpleContentType(); - //add non-grouped properties - contentType.AddPropertyType(new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "nonGrouped1") { Name = "Non Grouped 1", Description = "", Mandatory = false, SortOrder = 1, DataTypeId = -88 }); - contentType.AddPropertyType(new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "nonGrouped2") { Name = "Non Grouped 2", Description = "", Mandatory = false, SortOrder = 1, DataTypeId = -88 }); + var contentType = ContentTypeBuilder.CreateSimpleContentType(); - //ensure that nothing is marked as dirty + // Add non-grouped properties + var pt1 = new PropertyTypeBuilder() + .WithAlias("nonGrouped1") + .WithName("Non Grouped 1") + .Build(); + var pt2 = new PropertyTypeBuilder() + .WithAlias("nonGrouped2") + .WithName("Non Grouped 2") + .Build(); + contentType.AddPropertyType(pt1); + contentType.AddPropertyType(pt2); + + // Ensure that nothing is marked as dirty contentType.ResetDirtyProperties(false); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - - var content = MockedContent.CreateSimpleContent(contentType); - //need to id the p + var content = ContentBuilder.CreateSimpleContent(contentType); var nonGrouped = content.GetNonGroupedProperties(); @@ -143,10 +134,10 @@ namespace Umbraco.Tests.Models [Test] public void All_Dirty_Properties_Get_Reset() { - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(false); @@ -161,10 +152,10 @@ namespace Umbraco.Tests.Models public void Can_Verify_Mocked_Content() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -176,10 +167,10 @@ namespace Umbraco.Tests.Models public void Can_Change_Property_Value() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // Act content.Properties["title"].SetValue("This is the new title"); @@ -194,10 +185,10 @@ namespace Umbraco.Tests.Models public void Can_Set_Property_Value_As_String() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // Act content.SetValue("title", "This is the new title"); @@ -212,10 +203,10 @@ namespace Umbraco.Tests.Models public void Can_Clone_Content_With_Reset_Identity() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); content.Id = 10; content.Key = new Guid("29181B97-CB8F-403F-86DE-5FEB497F4800"); @@ -243,9 +234,9 @@ namespace Umbraco.Tests.Models public void Can_Deep_Clone_Perf_Test() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); contentType.Id = 99; - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); var i = 200; foreach (var property in content.Properties) { @@ -291,12 +282,12 @@ namespace Umbraco.Tests.Models public void Can_Deep_Clone() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); contentType.Id = 99; contentType.Variations = ContentVariation.Culture; Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); content.SetCultureName("Hello", "en-US"); content.SetCultureName("World", "es-ES"); @@ -313,6 +304,7 @@ namespace Umbraco.Tests.Models { property.Id = ++i; } + content.Id = 10; content.CreateDate = DateTime.Now; content.CreatorId = 22; @@ -326,8 +318,6 @@ namespace Umbraco.Tests.Models content.UpdateDate = DateTime.Now; content.WriterId = 23; - - // Act var clone = (Content)content.DeepClone(); @@ -378,20 +368,25 @@ namespace Umbraco.Tests.Models Assert.AreEqual(clone.CultureInfos[key], content.CultureInfos[key]); } - //This double verifies by reflection + // This double verifies by reflection var allProps = clone.GetType().GetProperties(); foreach (var propertyInfo in allProps) { Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(content, null)); } - //need to ensure the event handlers are wired + // Need to ensure the event handlers are wired var asDirty = (ICanBeDirty)clone; Assert.IsFalse(asDirty.IsPropertyDirty("Properties")); - var propertyType = new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "blah"); - var newProperty = new Property(1, propertyType); + var propertyType = new PropertyTypeBuilder() + .WithAlias("blah") + .Build(); + var newProperty = new PropertyBuilder() + .WithId(1) + .WithPropertyType(propertyType) + .Build(); newProperty.SetValue("blah"); clone.Properties.Add(newProperty); @@ -402,12 +397,12 @@ namespace Umbraco.Tests.Models public void Remember_Dirty_Properties() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); contentType.Id = 99; contentType.Variations = ContentVariation.Culture; Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); content.SetCultureName("Hello", "en-US"); content.SetCultureName("World", "es-ES"); @@ -418,6 +413,7 @@ namespace Umbraco.Tests.Models { property.Id = ++i; } + content.Id = 10; content.CreateDate = DateTime.Now; content.CreatorId = 22; @@ -427,7 +423,6 @@ namespace Umbraco.Tests.Models content.Path = "-1,4,10"; content.SortOrder = 5; content.TemplateId = 88; - content.Trashed = true; content.UpdateDate = DateTime.Now; content.WriterId = 23; @@ -454,6 +449,7 @@ namespace Umbraco.Tests.Models Assert.IsTrue(prop.WasDirty()); Assert.IsTrue(prop.WasPropertyDirty("Id")); } + Assert.IsTrue(content.WasPropertyDirty("CultureInfos")); foreach (var culture in content.CultureInfos) { @@ -461,6 +457,7 @@ namespace Umbraco.Tests.Models Assert.IsTrue(culture.WasPropertyDirty("Name")); Assert.IsTrue(culture.WasPropertyDirty("Date")); } + Assert.IsTrue(content.WasPropertyDirty("PublishCultureInfos")); foreach (var culture in content.PublishCultureInfos) { @@ -474,16 +471,17 @@ namespace Umbraco.Tests.Models public void Can_Serialize_Without_Error() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); contentType.Id = 99; Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); var i = 200; foreach (var property in content.Properties) { property.Id = ++i; } + content.Id = 10; content.CreateDate = DateTime.Now; content.CreatorId = 22; @@ -506,8 +504,8 @@ namespace Umbraco.Tests.Models public void Cannot_Change_Property_With_Invalid_Value() { // Arrange - var contentType = MockedContentTypes.CreateTextpageContentType(); - var content = MockedContent.CreateTextpageContent(contentType); + var contentType = ContentTypeBuilder.CreateTextpageContentType(); + var content = ContentBuilder.CreateTextpageContent(contentType); // Act var model = new TestEditorModel @@ -527,10 +525,10 @@ namespace Umbraco.Tests.Models public void Can_Change_Property_Value_Through_Anonymous_Object() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // Act content.PropertyValues(new { title = "This is the new title" }); @@ -547,10 +545,10 @@ namespace Umbraco.Tests.Models public void Can_Verify_Dirty_Property_On_Content() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // Act content.ResetDirtyProperties(); @@ -565,7 +563,7 @@ namespace Umbraco.Tests.Models public void Can_Add_PropertyGroup_On_ContentType() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); // Act contentType.PropertyGroups.Add(new PropertyGroup(true) { Name = "Test Group", SortOrder = 3 }); @@ -578,7 +576,7 @@ namespace Umbraco.Tests.Models public void Can_Remove_PropertyGroup_From_ContentType() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); contentType.ResetDirtyProperties(); // Act @@ -593,17 +591,14 @@ namespace Umbraco.Tests.Models public void Can_Add_PropertyType_To_Group_On_ContentType() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); // Act - contentType.PropertyGroups["Content"].PropertyTypes.Add(new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "subtitle") - { - Name = "Subtitle", - Description = "Optional subtitle", - Mandatory = false, - SortOrder = 3, - DataTypeId = -88 - }); + var propertyType = new PropertyTypeBuilder() + .WithAlias("subtitle") + .WithName("Subtitle") + .Build(); + contentType.PropertyGroups["Content"].PropertyTypes.Add(propertyType); // Assert Assert.That(contentType.PropertyGroups["Content"].PropertyTypes.Count, Is.EqualTo(3)); @@ -613,20 +608,16 @@ namespace Umbraco.Tests.Models public void Can_Add_New_Property_To_New_PropertyType() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // Act - var propertyType = new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "subtitle") - { - Name = "Subtitle", - Description = "Optional subtitle", - Mandatory = false, - SortOrder = 3, - DataTypeId = -88 - }; + var propertyType = new PropertyTypeBuilder() + .WithAlias("subtitle") + .WithName("Subtitle") + .Build(); contentType.PropertyGroups["Content"].PropertyTypes.Add(propertyType); var newProperty = new Property(propertyType); newProperty.SetValue("This is a subtitle Test"); @@ -641,20 +632,16 @@ namespace Umbraco.Tests.Models public void Can_Add_New_Property_To_New_PropertyType_In_New_PropertyGroup() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // Act - var propertyType = new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "subtitle") - { - Name = "Subtitle", - Description = "Optional subtitle", - Mandatory = false, - SortOrder = 3, - DataTypeId = -88 - }; + var propertyType = new PropertyTypeBuilder() + .WithAlias("subtitle") + .WithName("Subtitle") + .Build(); var propertyGroup = new PropertyGroup(true) { Name = "Test Group", SortOrder = 3 }; propertyGroup.PropertyTypes.Add(propertyType); contentType.PropertyGroups.Add(propertyGroup); @@ -672,20 +659,16 @@ namespace Umbraco.Tests.Models public void Can_Update_PropertyType_Through_Content_Properties() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // Act - note that the PropertyType's properties like SortOrder is not updated through the Content object - var propertyType = new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "title") - { - Name = "Title", - Description = "Title description added", - Mandatory = false, - SortOrder = 10, - DataTypeId = -88 - }; + var propertyType = new PropertyTypeBuilder() + .WithAlias("title") + .WithName("Title") + .Build(); content.Properties.Add(new Property(propertyType)); // Assert @@ -698,11 +681,11 @@ namespace Umbraco.Tests.Models public void Can_Change_ContentType_On_Content() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); - var simpleContentType = MockedContentTypes.CreateSimpleContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); + var simpleContentType = ContentTypeBuilder.CreateSimpleContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // Act content.ChangeContentType(simpleContentType); @@ -717,11 +700,11 @@ namespace Umbraco.Tests.Models public void Can_Change_ContentType_On_Content_And_Set_Property_Value() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); - var simpleContentType = MockedContentTypes.CreateSimpleContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); + var simpleContentType = ContentTypeBuilder.CreateSimpleContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // Act content.ChangeContentType(simpleContentType); @@ -736,11 +719,11 @@ namespace Umbraco.Tests.Models public void Can_Change_ContentType_On_Content_And_Still_Get_Old_Properties() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); - var simpleContentType = MockedContentTypes.CreateSimpleContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); + var simpleContentType = ContentTypeBuilder.CreateSimpleContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); // Act content.ChangeContentType(simpleContentType); @@ -761,9 +744,9 @@ namespace Umbraco.Tests.Models //Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); //// Arrange - //var contentType = MockedContentTypes.CreateTextPageContentType(); - //var simpleContentType = MockedContentTypes.CreateSimpleContentType(); - //var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + //var contentType = ContentTypeBuilder.CreateTextPageContentType(); + //var simpleContentType = ContentTypeBuilder.CreateSimpleContentType(); + //var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); //// Act //content.ChangeContentType(simpleContentType, true); @@ -777,10 +760,10 @@ namespace Umbraco.Tests.Models [Test] public void Can_Verify_Content_Is_Published() { - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(); content.PublishedState = PublishedState.Publishing; @@ -813,7 +796,7 @@ namespace Umbraco.Tests.Models public void Adding_PropertyGroup_To_ContentType_Results_In_Dirty_Entity() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); contentType.ResetDirtyProperties(); // Act @@ -830,7 +813,7 @@ namespace Umbraco.Tests.Models public void After_Committing_Changes_Was_Dirty_Is_True() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); contentType.ResetDirtyProperties(); //reset // Act @@ -847,11 +830,11 @@ namespace Umbraco.Tests.Models public void After_Committing_Changes_Was_Dirty_Is_True_On_Changed_Property() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); contentType.ResetDirtyProperties(); //reset Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); - var content = MockedContent.CreateTextpageContent(contentType, "test", -1); + var content = ContentBuilder.CreateTextpageContent(contentType, "test", -1); content.ResetDirtyProperties(); // Act @@ -880,7 +863,7 @@ namespace Umbraco.Tests.Models public void If_Not_Committed_Was_Dirty_Is_False() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); // Act contentType.Alias = "newAlias"; @@ -894,7 +877,7 @@ namespace Umbraco.Tests.Models public void Detect_That_A_Property_Is_Removed() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); Assert.That(contentType.WasPropertyDirty("HasPropertyTypeBeenRemoved"), Is.False); // Act @@ -908,18 +891,14 @@ namespace Umbraco.Tests.Models public void Adding_PropertyType_To_PropertyGroup_On_ContentType_Results_In_Dirty_Entity() { // Arrange - var contentType = MockedContentTypes.CreateTextPageContentType(); + var contentType = ContentTypeBuilder.CreateTextPageContentType(); contentType.ResetDirtyProperties(); // Act - var propertyType = new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "subtitle") - { - Name = "Subtitle", - Description = "Optional subtitle", - Mandatory = false, - SortOrder = 3, - DataTypeId = -88 - }; + var propertyType = new PropertyTypeBuilder() + .WithAlias("subtitle") + .WithName("Subtitle") + .Build(); contentType.PropertyGroups["Content"].PropertyTypes.Add(propertyType); // Assert @@ -932,20 +911,13 @@ namespace Umbraco.Tests.Models public void Can_Compose_Composite_ContentType_Collection() { // Arrange - var simpleContentType = MockedContentTypes.CreateSimpleContentType(); - var simple2ContentType = MockedContentTypes.CreateSimpleContentType("anotherSimple", "Another Simple Page", - new PropertyTypeCollection(true, - new List - { - new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "coauthor") - { - Name = "Co-Author", - Description = "Name of the Co-Author", - Mandatory = false, - SortOrder = 4, - DataTypeId = -88 - } - })); + var simpleContentType = ContentTypeBuilder.CreateSimpleContentType(); + var propertyType = new PropertyTypeBuilder() + .WithAlias("coauthor") + .WithName("Co-author") + .Build(); + var simple2ContentType = ContentTypeBuilder.CreateSimpleContentType("anotherSimple", "Another Simple Page", + propertyTypeCollection: new PropertyTypeCollection(true, new List { propertyType })); // Act var added = simpleContentType.AddContentType(simple2ContentType); @@ -962,21 +934,14 @@ namespace Umbraco.Tests.Models public void Can_Compose_Nested_Composite_ContentType_Collection() { // Arrange - var metaContentType = MockedContentTypes.CreateMetaContentType(); - var simpleContentType = MockedContentTypes.CreateSimpleContentType(); - var simple2ContentType = MockedContentTypes.CreateSimpleContentType("anotherSimple", "Another Simple Page", - new PropertyTypeCollection(true, - new List - { - new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "coauthor") - { - Name = "Co-Author", - Description = "Name of the Co-Author", - Mandatory = false, - SortOrder = 4, - DataTypeId = -88 - } - })); + var metaContentType = ContentTypeBuilder.CreateMetaContentType(); + var simpleContentType = ContentTypeBuilder.CreateSimpleContentType(); + var propertyType = new PropertyTypeBuilder() + .WithAlias("coauthor") + .WithName("Co-author") + .Build(); + var simple2ContentType = ContentTypeBuilder.CreateSimpleContentType("anotherSimple", "Another Simple Page", + propertyTypeCollection: new PropertyTypeCollection(true, new List { propertyType })); // Act var addedMeta = simple2ContentType.AddContentType(metaContentType); @@ -995,33 +960,21 @@ namespace Umbraco.Tests.Models [Test] public void Can_Avoid_Circular_Dependencies_In_Composition() { - var textPage = MockedContentTypes.CreateTextPageContentType(); - var parent = MockedContentTypes.CreateSimpleContentType("parent", "Parent", null, true); - var meta = MockedContentTypes.CreateMetaContentType(); - var mixin1 = MockedContentTypes.CreateSimpleContentType("mixin1", "Mixin1", new PropertyTypeCollection(true, - new List - { - new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "coauthor") - { - Name = "Co-Author", - Description = "Name of the Co-Author", - Mandatory = false, - SortOrder = 4, - DataTypeId = -88 - } - })); - var mixin2 = MockedContentTypes.CreateSimpleContentType("mixin2", "Mixin2", new PropertyTypeCollection(true, - new List - { - new PropertyType(ShortStringHelper, "test", ValueStorageType.Ntext, "author") - { - Name = "Author", - Description = "Name of the Author", - Mandatory = false, - SortOrder = 4, - DataTypeId = -88 - } - })); + var textPage = ContentTypeBuilder.CreateTextPageContentType(); + var parent = ContentTypeBuilder.CreateSimpleContentType("parent", "Parent", null, randomizeAliases: true); + var meta = ContentTypeBuilder.CreateMetaContentType(); + var propertyType1 = new PropertyTypeBuilder() + .WithAlias("coauthor") + .WithName("Co-author") + .Build(); + var mixin1 = ContentTypeBuilder.CreateSimpleContentType("mixin1", "Mixin1", + propertyTypeCollection: new PropertyTypeCollection(true, new List { propertyType1 })); + var propertyType2 = new PropertyTypeBuilder() + .WithAlias("author") + .WithName("Author") + .Build(); + var mixin2 = ContentTypeBuilder.CreateSimpleContentType("mixin2", "Mixin2", + propertyTypeCollection: new PropertyTypeCollection(true, new List { propertyType2 })); // Act var addedMetaMixin2 = mixin2.AddContentType(meta); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/ContentTypeTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentTypeTests.cs similarity index 99% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/ContentTypeTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentTypeTests.cs index d5ba104d78..c571a79785 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/ContentTypeTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/ContentTypeTests.cs @@ -3,13 +3,12 @@ using System.Diagnostics; using System.Linq; using Newtonsoft.Json; using NUnit.Framework; -using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class ContentTypeTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/CultureImpactTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/CultureImpactTests.cs similarity index 98% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/CultureImpactTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/CultureImpactTests.cs index dd782ee1c4..753c0e2b4d 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/CultureImpactTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/CultureImpactTests.cs @@ -2,7 +2,7 @@ using NUnit.Framework; using Umbraco.Core.Models; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class CultureImpactTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DeepCloneHelperTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DeepCloneHelperTests.cs similarity index 99% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DeepCloneHelperTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DeepCloneHelperTests.cs index 525b8bec0f..fcad67c221 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DeepCloneHelperTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DeepCloneHelperTests.cs @@ -5,7 +5,7 @@ using System.Linq; using NUnit.Framework; using Umbraco.Core.Models; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class DeepCloneHelperTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DictionaryItemTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DictionaryItemTests.cs similarity index 96% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DictionaryItemTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DictionaryItemTests.cs index 44a62521f3..54a935c891 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DictionaryItemTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DictionaryItemTests.cs @@ -4,7 +4,7 @@ using NUnit.Framework; using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class DictionaryItemTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DictionaryTranslationTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DictionaryTranslationTests.cs similarity index 97% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DictionaryTranslationTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DictionaryTranslationTests.cs index 0badf150b6..957acf293e 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DictionaryTranslationTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DictionaryTranslationTests.cs @@ -6,7 +6,7 @@ using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class DictionaryTranslationTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DocumentEntityTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DocumentEntityTests.cs similarity index 94% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DocumentEntityTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DocumentEntityTests.cs index 3f79675d06..1829720aad 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DocumentEntityTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/DocumentEntityTests.cs @@ -4,7 +4,7 @@ using NUnit.Framework; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class DocumentEntityTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/LanguageTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/LanguageTests.cs similarity index 96% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/LanguageTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/LanguageTests.cs index eb2ae7235a..5b1fc2d56b 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/LanguageTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/LanguageTests.cs @@ -4,7 +4,7 @@ using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class LanguageTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/MacroTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/MacroTests.cs similarity index 97% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/MacroTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/MacroTests.cs index 9137c67e7e..9d22387cd6 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/MacroTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/MacroTests.cs @@ -6,7 +6,7 @@ using Umbraco.Core.Models.Entities; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class MacroTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/MemberGroupTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/MemberGroupTests.cs similarity index 97% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/MemberGroupTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/MemberGroupTests.cs index 6c539c969a..47138a5fb4 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/MemberGroupTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/MemberGroupTests.cs @@ -6,7 +6,7 @@ using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class MemberGroupTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/MemberTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/MemberTests.cs similarity index 97% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/MemberTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/MemberTests.cs index 8092342e90..58f88affa1 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/MemberTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/MemberTests.cs @@ -1,14 +1,12 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using System.Linq; using Newtonsoft.Json; using NUnit.Framework; -using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class MemberTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PropertyGroupTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/PropertyGroupTests.cs similarity index 97% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PropertyGroupTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/PropertyGroupTests.cs index 81ea9d9443..08e025a6b1 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PropertyGroupTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/PropertyGroupTests.cs @@ -6,7 +6,7 @@ using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class PropertyGroupTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PropertyTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/PropertyTests.cs similarity index 96% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PropertyTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/PropertyTests.cs index dbf0dfc2f3..ce87174d7c 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PropertyTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/PropertyTests.cs @@ -5,7 +5,7 @@ using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class PropertyTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PropertyTypeTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/PropertyTypeTests.cs similarity index 97% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PropertyTypeTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/PropertyTypeTests.cs index f2b568054c..6fa061b1d2 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PropertyTypeTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/PropertyTypeTests.cs @@ -8,7 +8,7 @@ using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class PropertyTypeTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/RelationTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/RelationTests.cs similarity index 97% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/RelationTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/RelationTests.cs index 3a6c85c721..fa7e540533 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/RelationTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/RelationTests.cs @@ -6,7 +6,7 @@ using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class RelationTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/RelationTypeTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/RelationTypeTests.cs similarity index 96% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/RelationTypeTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/RelationTypeTests.cs index b96d937c72..2d5b88d945 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/RelationTypeTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/RelationTypeTests.cs @@ -5,7 +5,7 @@ using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class RelationTypeTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/StylesheetTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/StylesheetTests.cs similarity index 98% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/StylesheetTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/StylesheetTests.cs index 386efcced8..f744fee829 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/StylesheetTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/StylesheetTests.cs @@ -6,7 +6,7 @@ using NUnit.Framework; using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class StylesheetTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/TemplateTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/TemplateTests.cs similarity index 97% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/TemplateTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/TemplateTests.cs index d76d2daed5..d1c731184e 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/TemplateTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/TemplateTests.cs @@ -8,7 +8,7 @@ using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class TemplateTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/UserExtensionsTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/UserExtensionsTests.cs similarity index 98% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/UserExtensionsTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/UserExtensionsTests.cs index d3d59e77ba..faf96a6457 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/UserExtensionsTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/UserExtensionsTests.cs @@ -8,7 +8,7 @@ using Umbraco.Core.Models.Entities; using Umbraco.Core.Services; using Umbraco.Tests.Common.Builders; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class UserExtensionsTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/UserTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/UserTests.cs similarity index 94% rename from src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/UserTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/UserTests.cs index db0761b165..e4b9f89067 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/UserTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/UserTests.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using System.Linq; using Newtonsoft.Json; using NUnit.Framework; @@ -7,7 +6,7 @@ using Umbraco.Core.Models.Membership; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class UserTests diff --git a/src/Umbraco.Tests/Models/VariationTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/VariationTests.cs similarity index 84% rename from src/Umbraco.Tests/Models/VariationTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/VariationTests.cs index df63461f4d..ec1d60ba1b 100644 --- a/src/Umbraco.Tests/Models/VariationTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/VariationTests.cs @@ -3,69 +3,21 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; using NUnit.Framework; using Umbraco.Core; -using Umbraco.Core.Composing; +using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Core.Strings; +using Umbraco.Tests.Common.Builders; +using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; -using Current = Umbraco.Web.Composing.Current; +using Umbraco.Web.PropertyEditors; -namespace Umbraco.Tests.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Models { [TestFixture] public class VariationTests { - private IFactory _factory; - private IShortStringHelper ShortStringHelper { get; } = TestHelper.ShortStringHelper; - - [SetUp] - public void SetUp() - { - // well, this is also annoying, but... - // validating a value is performed by its data editor, - // based upon the configuration in the data type, so we - // need to be able to retrieve them all... - - Current.Reset(); - - _factory = Mock.Of(); - - var dataTypeService = Mock.Of(); - var localizationService = Mock.Of(); - - var dataEditors = new DataEditorCollection(new IDataEditor[] - { - new DataEditor(NullLoggerFactory.Instance, Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of()) { Alias = "editor", ExplicitValueEditor = MockedValueEditors.CreateDataValueEditor("view") } - }); - var propertyEditors = new PropertyEditorCollection(dataEditors); - - var dataType = Mock.Of(); - Mock.Get(dataType) - .Setup(x => x.Configuration) - .Returns(null); - - Mock.Get(dataTypeService) - .Setup(x => x.GetDataType(It.IsAny())) - .Returns(x => dataType); - - var serviceContext = ServiceContext.CreatePartial( - dataTypeService: dataTypeService, - localizedTextService: Mock.Of()); - - Mock.Get(_factory) - .Setup(x => x.GetInstance(It.IsAny())) - .Returns(x => - { - //if (x == typeof(Configs)) return configs; - if (x == typeof(PropertyEditorCollection)) return propertyEditors; - if (x == typeof(ServiceContext)) return serviceContext; - if (x == typeof(ILocalizedTextService)) return serviceContext.LocalizationService; - throw new NotSupportedException(x.FullName); - }); - } - [Test] public void ValidateVariationTests() { @@ -292,8 +244,10 @@ namespace Umbraco.Tests.Models [Test] public void ContentNames() { - var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" }; - var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; + var contentType = new ContentTypeBuilder() + .WithAlias("contentType") + .Build(); + var content = CreateContent(contentType); const string langFr = "fr-FR"; const string langUk = "en-UK"; @@ -305,7 +259,7 @@ namespace Umbraco.Tests.Models contentType.Variations = ContentVariation.Culture; // recreate content to re-capture content type variations - content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; + content = CreateContent(contentType); // invariant name works content.Name = "name"; @@ -333,11 +287,15 @@ namespace Umbraco.Tests.Models { const string langFr = "fr-FR"; - var propertyType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop" }; - var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" }; + var propertyType = new PropertyTypeBuilder() + .WithAlias("prop") + .Build(); + var contentType = new ContentTypeBuilder() + .WithAlias("contentType") + .Build(); contentType.AddPropertyType(propertyType); - var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; + var content = CreateContent(contentType); // can set value // and get edited value, published is null @@ -419,7 +377,8 @@ namespace Umbraco.Tests.Models Assert.IsNull(content.GetValue("prop")); Assert.IsNull(content.GetValue("prop", published: true)); - var other = new Content("other", -1, contentType) { Id = 2, VersionId = 1 }; + var other = CreateContent(contentType, 2, "other"); + Assert.Throws(() => other.SetValue("prop", "o")); // don't even try other.SetValue("prop", "o1", langFr); @@ -441,26 +400,32 @@ namespace Umbraco.Tests.Models [Test] public void ContentPublishValuesWithMixedPropertyTypeVariations() { - var propertyValidationService = new PropertyValidationService( - _factory.GetInstance(), - _factory.GetInstance().DataTypeService, - _factory.GetInstance().TextService); + var propertyValidationService = GetPropertyValidationService(); const string langFr = "fr-FR"; // content type varies by Culture // prop1 varies by Culture // prop2 is invariant - var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" }; + var contentType = new ContentTypeBuilder() + .WithAlias("contentType") + .Build(); contentType.Variations |= ContentVariation.Culture; - var variantPropType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop1", Variations = ContentVariation.Culture, Mandatory = true }; - var invariantPropType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop2", Variations = ContentVariation.Nothing, Mandatory = true}; - + var variantPropType = new PropertyTypeBuilder() + .WithAlias("prop1") + .WithVariations(ContentVariation.Culture) + .WithMandatory(true) + .Build(); + var invariantPropType = new PropertyTypeBuilder() + .WithAlias("prop2") + .WithVariations(ContentVariation.Nothing) + .WithMandatory(true) + .Build(); contentType.AddPropertyType(variantPropType); contentType.AddPropertyType(invariantPropType); - var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; + var content = CreateContent(contentType); content.SetCultureName("hello", langFr); @@ -490,11 +455,15 @@ namespace Umbraco.Tests.Models const string langUk = "en-UK"; const string langEs = "es-ES"; - var propertyType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop" }; - var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" }; + var propertyType = new PropertyTypeBuilder() + .WithAlias("prop") + .Build(); + var contentType = new ContentTypeBuilder() + .WithAlias("contentType") + .Build(); contentType.AddPropertyType(propertyType); - var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; + var content = CreateContent(contentType); // change - now we vary by culture contentType.Variations |= ContentVariation.Culture; @@ -545,12 +514,16 @@ namespace Umbraco.Tests.Models [Test] public void IsDirtyTests() { - var propertyType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop" }; + var propertyType = new PropertyTypeBuilder() + .WithAlias("prop") + .Build(); var prop = new Property(propertyType); - var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" }; + var contentType = new ContentTypeBuilder() + .WithAlias("contentType") + .Build(); contentType.AddPropertyType(propertyType); - var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; + var content = CreateContent(contentType); prop.SetValue("a"); Assert.AreEqual("a", prop.GetValue()); @@ -570,17 +543,17 @@ namespace Umbraco.Tests.Models [Test] public void ValidationTests() { - var propertyType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop", SupportsPublishing = true }; + var propertyType = new PropertyTypeBuilder() + .WithAlias("prop") + .WithSupportsPublishing(true) + .Build(); + var prop = new Property(propertyType); prop.SetValue("a"); Assert.AreEqual("a", prop.GetValue()); Assert.IsNull(prop.GetValue(published: true)); - var propertyValidationService = new PropertyValidationService( - _factory.GetInstance(), - _factory.GetInstance().DataTypeService, - _factory.GetInstance().TextService - ); + var propertyValidationService = GetPropertyValidationService(); Assert.IsTrue(propertyValidationService.IsPropertyValid(prop)); @@ -593,5 +566,43 @@ namespace Umbraco.Tests.Models // can publish, even though invalid prop.PublishValues(); } + + private static Content CreateContent(IContentType contentType, int id = 1, string name = "content") + { + return new ContentBuilder() + .WithId(id) + .WithVersionId(1) + .WithName(name) + .WithContentType(contentType) + .Build(); + } + + private static PropertyValidationService GetPropertyValidationService() + { + var ioHelper = Mock.Of(); + var dataTypeService = Mock.Of(); + var localizedTextService = Mock.Of(); + var localizationService = Mock.Of(); + var shortStringHelper = Mock.Of(); + + var textBoxEditor = new TextboxPropertyEditor( + NullLoggerFactory.Instance, + dataTypeService, + localizationService, + ioHelper, + shortStringHelper, + localizedTextService + ); + + var mockDataTypeService = new Mock(); + Mock.Get(dataTypeService).Setup(x => x.GetDataType(It.Is(y => y == Constants.DataTypes.Textbox))) + .Returns(new DataType(textBoxEditor)); + + var propertyEditorCollection = new PropertyEditorCollection(new DataEditorCollection(new[] { textBoxEditor })); + return new PropertyValidationService( + propertyEditorCollection, + dataTypeService, + localizedTextService); + } } } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Packaging/PackageExtractionTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Packaging/PackageExtractionTests.cs index ad76b060ce..48f26f210c 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Packaging/PackageExtractionTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Packaging/PackageExtractionTests.cs @@ -5,7 +5,7 @@ using NUnit.Framework; using Umbraco.Core.Hosting; using Umbraco.Core.Packaging; -namespace Umbraco.Tests.Packaging +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Packaging { [TestFixture] public class PackageExtractionTests @@ -14,7 +14,7 @@ namespace Umbraco.Tests.Packaging private static FileInfo GetTestPackagePath(string packageName) { - const string testPackagesDirName = "Umbraco.Core\\Packaging\\Packages"; + var testPackagesDirName = Path.Combine("Umbraco.Core","Packaging","Packages"); var testDir = TestContext.CurrentContext.TestDirectory.Split("bin")[0]; var path = Path.Combine(testDir, testPackagesDirName, packageName); return new FileInfo(path); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/BlockEditorComponentTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/BlockEditorComponentTests.cs index 1636936615..bc54a7b999 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/BlockEditorComponentTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/BlockEditorComponentTests.cs @@ -6,7 +6,7 @@ using System.Linq; using Umbraco.Core; using Umbraco.Web.Compose; -namespace Umbraco.Tests.PropertyEditors +namespace Umbraco.Tests.UnitTests.Umbraco.Core.PropertyEditors { [TestFixture] public class BlockEditorComponentTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/BlockListPropertyValueConverterTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/BlockListPropertyValueConverterTests.cs index 5d664c9c76..eb77ad2e1c 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/BlockListPropertyValueConverterTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/BlockListPropertyValueConverterTests.cs @@ -13,7 +13,7 @@ using Umbraco.Web.PropertyEditors; using Umbraco.Web.PropertyEditors.ValueConverters; using Umbraco.Web.PublishedCache; -namespace Umbraco.Tests.PropertyEditors +namespace Umbraco.Tests.UnitTests.Umbraco.Core.PropertyEditors { [TestFixture] public class BlockListPropertyValueConverterTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/ColorListValidatorTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/ColorListValidatorTest.cs index f96e265e1f..14aa628f88 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/ColorListValidatorTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/ColorListValidatorTest.cs @@ -11,7 +11,7 @@ using Umbraco.Core.Strings; using Umbraco.Tests.TestHelpers; using Umbraco.Web.PropertyEditors; -namespace Umbraco.Tests.PropertyEditors +namespace Umbraco.Tests.UnitTests.Umbraco.Core.PropertyEditors { [TestFixture] public class ColorListValidatorTest diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs index a2224b0c5a..85c7af9313 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs @@ -16,7 +16,7 @@ using Umbraco.Tests.TestHelpers; using Umbraco.Web.PropertyEditors; using static Umbraco.Core.Models.Property; -namespace Umbraco.Tests.PropertyEditors +namespace Umbraco.Tests.UnitTests.Umbraco.Core.PropertyEditors { [TestFixture] public class DataValueReferenceFactoryCollectionTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/EnsureUniqueValuesValidatorTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/EnsureUniqueValuesValidatorTest.cs index 3383803c4a..44c53382d9 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/EnsureUniqueValuesValidatorTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/EnsureUniqueValuesValidatorTest.cs @@ -11,7 +11,7 @@ using Umbraco.Core.Strings; using Umbraco.Tests.TestHelpers; using Umbraco.Web.PropertyEditors; -namespace Umbraco.Tests.PropertyEditors +namespace Umbraco.Tests.UnitTests.Umbraco.Core.PropertyEditors { [TestFixture] public class EnsureUniqueValuesValidatorTest diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/MultiValuePropertyEditorTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/MultiValuePropertyEditorTests.cs index de02ccc713..675951cad1 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/MultiValuePropertyEditorTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/MultiValuePropertyEditorTests.cs @@ -12,7 +12,7 @@ using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Web.PropertyEditors; -namespace Umbraco.Tests.PropertyEditors +namespace Umbraco.Tests.UnitTests.Umbraco.Core.PropertyEditors { /// /// Tests for the base classes of ValueEditors and PreValueEditors that are used for Property Editors that edit diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/NestedContentPropertyComponentTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/NestedContentPropertyComponentTests.cs index 5b7e220123..930f1b623f 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/NestedContentPropertyComponentTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/NestedContentPropertyComponentTests.cs @@ -7,7 +7,7 @@ using System.Text; using System.Threading.Tasks; using Umbraco.Web.Compose; -namespace Umbraco.Tests.PropertyEditors +namespace Umbraco.Tests.UnitTests.Umbraco.Core.PropertyEditors { [TestFixture] diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueConverterTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueConverterTests.cs index dfd0e29674..be72eff1e7 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueConverterTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueConverterTests.cs @@ -13,7 +13,7 @@ using Umbraco.Tests.TestHelpers; using Umbraco.Web.PropertyEditors; using Umbraco.Web.PropertyEditors.ValueConverters; -namespace Umbraco.Tests.PropertyEditors +namespace Umbraco.Tests.UnitTests.Umbraco.Core.PropertyEditors { [TestFixture] public class PropertyEditorValueConverterTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueEditorTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueEditorTests.cs index e5d93a13da..4fe391d1e9 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueEditorTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueEditorTests.cs @@ -10,7 +10,7 @@ using Umbraco.Core.PropertyEditors; using Umbraco.Core.Strings; using Umbraco.Tests.TestHelpers.Entities; -namespace Umbraco.Tests.PropertyEditors +namespace Umbraco.Tests.UnitTests.Umbraco.Core.PropertyEditors { [TestFixture] public class PropertyEditorValueEditorTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ConvertersTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ConvertersTests.cs index 62d7f422fe..2c444ee67d 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ConvertersTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ConvertersTests.cs @@ -14,7 +14,7 @@ using Umbraco.Core.Strings; using Umbraco.Tests.Common.PublishedContent; using Umbraco.Web.PublishedCache; -namespace Umbraco.Tests.Published +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Published { [TestFixture] public class ConvertersTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ModelTypeTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ModelTypeTests.cs index 43d5b56d6b..9b4f377247 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ModelTypeTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ModelTypeTests.cs @@ -2,8 +2,9 @@ using System; using System.Collections.Generic; using NUnit.Framework; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Tests.Published; -namespace Umbraco.Tests.Published +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Published { [TestFixture] public class ModelTypeTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/NestedContentTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/NestedContentTests.cs index a3aae7b7dc..1b7ebec5ec 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/NestedContentTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/NestedContentTests.cs @@ -19,7 +19,7 @@ using Umbraco.Web.PropertyEditors; using Umbraco.Web.PropertyEditors.ValueConverters; using Umbraco.Web.PublishedCache; -namespace Umbraco.Tests.Published +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Published { [TestFixture] public class NestedContentTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PropertyCacheLevelTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PropertyCacheLevelTests.cs index 42a2234d64..f30029c94c 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PropertyCacheLevelTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PropertyCacheLevelTests.cs @@ -13,7 +13,7 @@ using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Web.PublishedCache; -namespace Umbraco.Tests.Published +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Published { [TestFixture] public class PropertyCacheLevelTests diff --git a/src/Umbraco.Tests/Routing/SiteDomainHelperTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Routing/SiteDomainHelperTests.cs similarity index 78% rename from src/Umbraco.Tests/Routing/SiteDomainHelperTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/Routing/SiteDomainHelperTests.cs index 1ef632b497..d32340b6b0 100644 --- a/src/Umbraco.Tests/Routing/SiteDomainHelperTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Routing/SiteDomainHelperTests.cs @@ -4,7 +4,7 @@ using System.Linq; using NUnit.Framework; using Umbraco.Web.Routing; -namespace Umbraco.Tests.Routing +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing { [TestFixture] public class SiteDomainHelperTests @@ -21,8 +21,8 @@ namespace Umbraco.Tests.Routing SiteDomainHelper.Clear(); // assuming this works! } - private static CultureInfo CultureFr = CultureInfo.GetCultureInfo("fr-fr"); - private static CultureInfo CultureUk = CultureInfo.GetCultureInfo("en-uk"); + private static CultureInfo _cultureFr = CultureInfo.GetCultureInfo("fr-fr"); + private static CultureInfo _cultureGb = CultureInfo.GetCultureInfo("en-gb"); [Test] public void AddSites() @@ -191,38 +191,38 @@ namespace Umbraco.Tests.Routing var current = new Uri("https://www.domain1.com/foo/bar"); var domainAndUris = DomainAndUris(current, new[] { - new Domain(1, "domain2.com", -1, CultureFr, false), - new Domain(1, "domain1.com", -1, CultureUk, false), + new Domain(1, "domain2.com", -1, _cultureFr, false), + new Domain(1, "domain1.com", -1, _cultureGb, false), }); - var output = helper.MapDomain(domainAndUris, current, CultureFr.Name, CultureFr.Name).Uri.ToString(); + var output = helper.MapDomain(domainAndUris, current, _cultureFr.Name, _cultureFr.Name).Uri.ToString(); Assert.AreEqual("https://domain1.com/", output); // will pick it all right current = new Uri("https://domain1.com/foo/bar"); domainAndUris = DomainAndUris(current, new[] { - new Domain(1, "https://domain1.com", -1, CultureFr, false), - new Domain(1, "https://domain2.com", -1, CultureUk, false) + new Domain(1, "https://domain1.com", -1, _cultureFr, false), + new Domain(1, "https://domain2.com", -1, _cultureGb, false) }); - output = helper.MapDomain(domainAndUris, current, CultureFr.Name, CultureFr.Name).Uri.ToString(); + output = helper.MapDomain(domainAndUris, current, _cultureFr.Name, _cultureFr.Name).Uri.ToString(); Assert.AreEqual("https://domain1.com/", output); current = new Uri("https://domain1.com/foo/bar"); domainAndUris = DomainAndUris(current, new[] { - new Domain(1, "https://domain1.com", -1, CultureFr, false), - new Domain(1, "https://domain4.com", -1, CultureUk, false) + new Domain(1, "https://domain1.com", -1, _cultureFr, false), + new Domain(1, "https://domain4.com", -1, _cultureGb, false) }); - output = helper.MapDomain(domainAndUris, current, CultureFr.Name, CultureFr.Name).Uri.ToString(); + output = helper.MapDomain(domainAndUris, current, _cultureFr.Name, _cultureFr.Name).Uri.ToString(); Assert.AreEqual("https://domain1.com/", output); current = new Uri("https://domain4.com/foo/bar"); domainAndUris = DomainAndUris(current, new[] { - new Domain(1, "https://domain1.com", -1, CultureFr, false), - new Domain(1, "https://domain4.com", -1, CultureUk, false) + new Domain(1, "https://domain1.com", -1, _cultureFr, false), + new Domain(1, "https://domain4.com", -1, _cultureGb, false) }); - output = helper.MapDomain(domainAndUris, current, CultureFr.Name, CultureFr.Name).Uri.ToString(); + output = helper.MapDomain(domainAndUris, current, _cultureFr.Name, _cultureFr.Name).Uri.ToString(); Assert.AreEqual("https://domain4.com/", output); } @@ -234,9 +234,6 @@ namespace Umbraco.Tests.Routing SiteDomainHelper.AddSite("site3", "domain3.com", "domain3.net", "domain3.org"); SiteDomainHelper.AddSite("site4", "domain4.com", "domain4.net", "domain4.org"); - //SiteDomainHelper.BindSites("site1", "site3"); - //SiteDomainHelper.BindSites("site2", "site4"); - // map methods are not static because we can override them var helper = new SiteDomainHelper(); @@ -246,9 +243,9 @@ namespace Umbraco.Tests.Routing var current = new Uri("http://domain1.com/foo/bar"); var output = helper.MapDomain(new[] { - new DomainAndUri(new Domain(1, "domain1.com", -1, CultureFr, false), current), - new DomainAndUri(new Domain(1, "domain2.com", -1, CultureUk, false), current), - }, current, CultureFr.Name, CultureFr.Name).Uri.ToString(); + new DomainAndUri(new Domain(1, "domain1.com", -1, _cultureFr, false), current), + new DomainAndUri(new Domain(1, "domain2.com", -1, _cultureGb, false), current), + }, current, _cultureFr.Name, _cultureFr.Name).Uri.ToString(); Assert.AreEqual("http://domain1.com/", output); // current is a site1 uri, domains do not contain current @@ -257,9 +254,9 @@ namespace Umbraco.Tests.Routing current = new Uri("http://domain1.com/foo/bar"); output = helper.MapDomain(new[] { - new DomainAndUri(new Domain(1, "domain1.net", -1, CultureFr, false), current), - new DomainAndUri(new Domain(1, "domain2.net", -1, CultureUk, false), current) - }, current, CultureFr.Name, CultureFr.Name).Uri.ToString(); + new DomainAndUri(new Domain(1, "domain1.net", -1, _cultureFr, false), current), + new DomainAndUri(new Domain(1, "domain2.net", -1, _cultureGb, false), current) + }, current, _cultureFr.Name, _cultureFr.Name).Uri.ToString(); Assert.AreEqual("http://domain1.net/", output); // current is a site1 uri, domains do not contain current @@ -269,9 +266,9 @@ namespace Umbraco.Tests.Routing current = new Uri("http://domain1.com/foo/bar"); output = helper.MapDomain(new[] { - new DomainAndUri(new Domain(1, "domain2.net", -1, CultureFr, false), current), - new DomainAndUri(new Domain(1, "domain1.net", -1, CultureUk, false), current) - }, current, CultureFr.Name, CultureFr.Name).Uri.ToString(); + new DomainAndUri(new Domain(1, "domain2.net", -1, _cultureFr, false), current), + new DomainAndUri(new Domain(1, "domain1.net", -1, _cultureGb, false), current) + }, current, _cultureFr.Name, _cultureFr.Name).Uri.ToString(); Assert.AreEqual("http://domain1.net/", output); } @@ -296,12 +293,12 @@ namespace Umbraco.Tests.Routing var current = new Uri("http://domain1.com/foo/bar"); var output = helper.MapDomains(new[] { - new DomainAndUri(new Domain(1, "domain1.com", -1, CultureFr, false), current), // no: current + what MapDomain would pick - new DomainAndUri(new Domain(1, "domain2.com", -1, CultureUk, false), current), // no: not same site - new DomainAndUri(new Domain(1, "domain3.com", -1, CultureUk, false), current), // no: not same site - new DomainAndUri(new Domain(1, "domain4.com", -1, CultureUk, false), current), // no: not same site - new DomainAndUri(new Domain(1, "domain1.org", -1, CultureUk, false), current), // yes: same site (though bogus setup) - }, current, true, CultureFr.Name, CultureFr.Name).ToArray(); + new DomainAndUri(new Domain(1, "domain1.com", -1, _cultureFr, false), current), // no: current + what MapDomain would pick + new DomainAndUri(new Domain(1, "domain2.com", -1, _cultureGb, false), current), // no: not same site + new DomainAndUri(new Domain(1, "domain3.com", -1, _cultureGb, false), current), // no: not same site + new DomainAndUri(new Domain(1, "domain4.com", -1, _cultureGb, false), current), // no: not same site + new DomainAndUri(new Domain(1, "domain1.org", -1, _cultureGb, false), current), // yes: same site (though bogus setup) + }, current, true, _cultureFr.Name, _cultureFr.Name).ToArray(); Assert.AreEqual(1, output.Count()); Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray()); @@ -311,12 +308,12 @@ namespace Umbraco.Tests.Routing current = new Uri("http://domain1.com/foo/bar"); output = helper.MapDomains(new[] { - new DomainAndUri(new Domain(1, "domain1.net", -1, CultureFr, false), current), // no: what MapDomain would pick - new DomainAndUri(new Domain(1, "domain2.com", -1, CultureUk, false), current), // no: not same site - new DomainAndUri(new Domain(1, "domain3.com", -1, CultureUk, false), current), // no: not same site - new DomainAndUri(new Domain(1, "domain4.com", -1, CultureUk, false), current), // no: not same site - new DomainAndUri(new Domain(1, "domain1.org", -1, CultureUk, false), current), // yes: same site (though bogus setup) - }, current, true, CultureFr.Name, CultureFr.Name).ToArray(); + new DomainAndUri(new Domain(1, "domain1.net", -1, _cultureFr, false), current), // no: what MapDomain would pick + new DomainAndUri(new Domain(1, "domain2.com", -1, _cultureGb, false), current), // no: not same site + new DomainAndUri(new Domain(1, "domain3.com", -1, _cultureGb, false), current), // no: not same site + new DomainAndUri(new Domain(1, "domain4.com", -1, _cultureGb, false), current), // no: not same site + new DomainAndUri(new Domain(1, "domain1.org", -1, _cultureGb, false), current), // yes: same site (though bogus setup) + }, current, true, _cultureFr.Name, _cultureFr.Name).ToArray(); Assert.AreEqual(1, output.Count()); Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray()); @@ -329,13 +326,13 @@ namespace Umbraco.Tests.Routing current = new Uri("http://domain1.com/foo/bar"); output = helper.MapDomains(new[] { - new DomainAndUri(new Domain(1, "domain1.com", -1, CultureFr, false), current), // no: current + what MapDomain would pick - new DomainAndUri(new Domain(1, "domain2.com", -1, CultureUk, false), current), // no: not same site - new DomainAndUri(new Domain(1, "domain3.com", -1, CultureUk, false), current), // yes: bound site - new DomainAndUri(new Domain(1, "domain3.org", -1, CultureUk, false), current), // yes: bound site - new DomainAndUri(new Domain(1, "domain4.com", -1, CultureUk, false), current), // no: not same site - new DomainAndUri(new Domain(1, "domain1.org", -1, CultureUk, false), current), // yes: same site (though bogus setup) - }, current, true, CultureFr.Name, CultureFr.Name).ToArray(); + new DomainAndUri(new Domain(1, "domain1.com", -1, _cultureFr, false), current), // no: current + what MapDomain would pick + new DomainAndUri(new Domain(1, "domain2.com", -1, _cultureGb, false), current), // no: not same site + new DomainAndUri(new Domain(1, "domain3.com", -1, _cultureGb, false), current), // yes: bound site + new DomainAndUri(new Domain(1, "domain3.org", -1, _cultureGb, false), current), // yes: bound site + new DomainAndUri(new Domain(1, "domain4.com", -1, _cultureGb, false), current), // no: not same site + new DomainAndUri(new Domain(1, "domain1.org", -1, _cultureGb, false), current), // yes: same site (though bogus setup) + }, current, true, _cultureFr.Name, _cultureFr.Name).ToArray(); Assert.AreEqual(3, output.Count()); Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray()); @@ -347,28 +344,18 @@ namespace Umbraco.Tests.Routing current = new Uri("http://domain1.com/foo/bar"); output = helper.MapDomains(new[] { - new DomainAndUri(new Domain(1, "domain1.net", -1, CultureFr, false), current), // no: what MapDomain would pick - new DomainAndUri(new Domain(1, "domain2.com", -1, CultureUk, false), current), // no: not same site - new DomainAndUri(new Domain(1, "domain3.com", -1, CultureUk, false), current), // yes: bound site - new DomainAndUri(new Domain(1, "domain3.org", -1, CultureUk, false), current), // yes: bound site - new DomainAndUri(new Domain(1, "domain4.com", -1, CultureUk, false), current), // no: not same site - new DomainAndUri(new Domain(1, "domain1.org", -1, CultureUk, false), current), // yes: same site (though bogus setup) - }, current, true, CultureFr.Name, CultureFr.Name).ToArray(); + new DomainAndUri(new Domain(1, "domain1.net", -1, _cultureFr, false), current), // no: what MapDomain would pick + new DomainAndUri(new Domain(1, "domain2.com", -1, _cultureGb, false), current), // no: not same site + new DomainAndUri(new Domain(1, "domain3.com", -1, _cultureGb, false), current), // yes: bound site + new DomainAndUri(new Domain(1, "domain3.org", -1, _cultureGb, false), current), // yes: bound site + new DomainAndUri(new Domain(1, "domain4.com", -1, _cultureGb, false), current), // no: not same site + new DomainAndUri(new Domain(1, "domain1.org", -1, _cultureGb, false), current), // yes: same site (though bogus setup) + }, current, true, _cultureFr.Name, _cultureFr.Name).ToArray(); Assert.AreEqual(3, output.Count()); Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray()); Assert.Contains("http://domain3.com/", output.Select(d => d.Uri.ToString()).ToArray()); Assert.Contains("http://domain3.org/", output.Select(d => d.Uri.ToString()).ToArray()); } - - //class MockDomain : Domain - //{ - // private static readonly FieldInfo NameField = typeof (Domain).GetField("_name", BindingFlags.Instance | BindingFlags.NonPublic); - - // public MockDomain(string name) - // { - // NameField.SetValue(this, name); - // } - //} } } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Scoping/EventNameExtractorTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Scoping/EventNameExtractorTests.cs index 82c74db64a..be3129aab0 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Scoping/EventNameExtractorTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Scoping/EventNameExtractorTests.cs @@ -2,7 +2,7 @@ using NUnit.Framework; using Umbraco.Core.Events; -namespace Umbraco.Tests.Scoping +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Scoping { [TestFixture] public class EventNameExtractorTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Services/ContentTypeServiceExtensionsTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Services/ContentTypeServiceExtensionsTests.cs index e1c82ced86..171a71b114 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Services/ContentTypeServiceExtensionsTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Services/ContentTypeServiceExtensionsTests.cs @@ -9,7 +9,7 @@ using Umbraco.Core.Strings; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.TestHelpers.Entities; -namespace Umbraco.Tests.Services +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Services { [TestFixture] public class ContentTypeServiceExtensionsTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/CmsHelperCasingTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/CmsHelperCasingTests.cs index a164242b2d..5be6a58692 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/CmsHelperCasingTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/CmsHelperCasingTests.cs @@ -10,7 +10,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Strings +namespace Umbraco.Tests.UnitTests.Umbraco.Core.ShortStringHelper { [TestFixture] public class CmsHelperCasingTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/DefaultShortStringHelperTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/DefaultShortStringHelperTests.cs index e89fe680b3..3241285fec 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/DefaultShortStringHelperTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/DefaultShortStringHelperTests.cs @@ -13,7 +13,7 @@ using Umbraco.Core.Strings; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Strings +namespace Umbraco.Tests.UnitTests.Umbraco.Core.ShortStringHelper { [TestFixture] public class DefaultShortStringHelperTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/DefaultShortStringHelperTestsWithoutSetup.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/DefaultShortStringHelperTestsWithoutSetup.cs index 829f520735..3a210c231d 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/DefaultShortStringHelperTestsWithoutSetup.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/DefaultShortStringHelperTestsWithoutSetup.cs @@ -6,8 +6,9 @@ using NUnit.Framework; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Strings; +using CoreStrings = Umbraco.Core.Strings; -namespace Umbraco.Tests.Strings +namespace Umbraco.Tests.UnitTests.Umbraco.Core.ShortStringHelper { [TestFixture] public class DefaultShortStringHelperTestsWithoutSetup @@ -300,7 +301,7 @@ namespace Umbraco.Tests.Strings public void Utf8ToAsciiConverter() { const string str = "a\U00010F00z\uA74Ftéô"; - var output = Core.Strings.Utf8ToAsciiConverter.ToAsciiString(str); + var output = CoreStrings.Utf8ToAsciiConverter.ToAsciiString(str); Assert.AreEqual("a?zooteo", output); } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/MockShortStringHelper.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/MockShortStringHelper.cs index 1cc959414d..442a655805 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/MockShortStringHelper.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/MockShortStringHelper.cs @@ -1,6 +1,6 @@ using Umbraco.Core.Strings; -namespace Umbraco.Tests.Strings +namespace Umbraco.Tests.UnitTests.Umbraco.Core.ShortStringHelper { class MockShortStringHelper : IShortStringHelper { diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StringExtensionsTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StringExtensionsTests.cs index 15d7ccc505..b3244f9884 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StringExtensionsTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StringExtensionsTests.cs @@ -9,7 +9,7 @@ using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Core.Strings; -namespace Umbraco.Tests.Strings +namespace Umbraco.Tests.UnitTests.Umbraco.Core.ShortStringHelper { [TestFixture] public class StringExtensionsTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StringValidationTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StringValidationTests.cs index 4de74b2828..cc786413f3 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StringValidationTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StringValidationTests.cs @@ -3,7 +3,7 @@ using NUnit.Framework; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Strings +namespace Umbraco.Tests.UnitTests.Umbraco.Core.ShortStringHelper { [TestFixture] public class StringValidationTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StylesheetHelperTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StylesheetHelperTests.cs index 46efce7a5b..950a103560 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StylesheetHelperTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/ShortStringHelper/StylesheetHelperTests.cs @@ -3,7 +3,7 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Strings.Css; -namespace Umbraco.Tests.Strings +namespace Umbraco.Tests.UnitTests.Umbraco.Core.ShortStringHelper { [TestFixture] public class StylesheetHelperTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/HtmlImageSourceParserTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/HtmlImageSourceParserTests.cs index 43c3f551e1..014bb0a299 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/HtmlImageSourceParserTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/HtmlImageSourceParserTests.cs @@ -13,7 +13,7 @@ using Umbraco.Tests.UnitTests.TestHelpers.Objects; using Umbraco.Web.Routing; using Umbraco.Web.Templates; -namespace Umbraco.Tests.Templates +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Templates { [TestFixture] public class HtmlImageSourceParserTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/HtmlLocalLinkParserTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/HtmlLocalLinkParserTests.cs index 7660265502..1acf676cba 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/HtmlLocalLinkParserTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/HtmlLocalLinkParserTests.cs @@ -11,7 +11,7 @@ using Umbraco.Tests.UnitTests.TestHelpers.Objects; using Umbraco.Web.Routing; using Umbraco.Web.Templates; -namespace Umbraco.Tests.Templates +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Templates { [TestFixture] public class HtmlLocalLinkParserTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/ViewHelperTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/ViewHelperTests.cs index 9f6da6c34a..27c78d7a68 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/ViewHelperTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/ViewHelperTests.cs @@ -1,7 +1,7 @@ using NUnit.Framework; using Umbraco.Core.IO; -namespace Umbraco.Tests.Templates +namespace Umbraco.Tests.UnitTests.Umbraco.Core.Templates { [TestFixture] public class ViewHelperTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Editors/UserEditorAuthorizationHelperTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Editors/UserEditorAuthorizationHelperTests.cs index 2fd0c7b8ea..642f9d335a 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Editors/UserEditorAuthorizationHelperTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Editors/UserEditorAuthorizationHelperTests.cs @@ -11,7 +11,7 @@ using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Web.Editors; -namespace Umbraco.Tests.Web.Controllers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Editors { [TestFixture] public class UserEditorAuthorizationHelperTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Examine/UmbracoContentValueSetValidatorTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Examine/UmbracoContentValueSetValidatorTests.cs index 643c56250d..449e005220 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Examine/UmbracoContentValueSetValidatorTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Examine/UmbracoContentValueSetValidatorTests.cs @@ -9,7 +9,7 @@ using Umbraco.Core.Models; using System; using System.Linq; -namespace Umbraco.Tests.UmbracoExamine +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Examine { [TestFixture] public class UmbracoContentValueSetValidatorTests @@ -20,7 +20,7 @@ namespace Umbraco.Tests.UmbracoExamine var validator = new ContentValueSetValidator(false, true, Mock.Of()); var result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" })); - Assert.AreEqual(ValueSetValidationResult.Valid, result); + Assert.AreEqual(ValueSetValidationResult.Valid, result); result = validator.Validate(ValueSet.FromObject("777", IndexTypes.Media, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationResult.Valid, result); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/HealthChecks/HealthCheckResultsTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/HealthChecks/HealthCheckResultsTests.cs index 39a9ca6211..387d8aff44 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/HealthChecks/HealthCheckResultsTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/HealthChecks/HealthCheckResultsTests.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; using NUnit.Framework; -using Umbraco.Core.Configuration.HealthChecks; +using Umbraco.Core.HealthCheck; +using Umbraco.Core.HealthCheck.Checks; +using Umbraco.Infrastructure.HealthCheck; using Umbraco.Web.HealthCheck; -namespace Umbraco.Tests.Web.HealthChecks +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.HealthChecks { [TestFixture] public class HealthCheckResultsTests @@ -135,7 +137,7 @@ namespace Umbraco.Tests.Web.HealthChecks var results = new HealthCheckResults(checks); var resultAsMarkdown = results.ResultsAsMarkDown(HealthCheckNotificationVerbosity.Summary); - Assert.IsTrue(resultAsMarkdown.IndexOf("Result: 'Success'\r\n") > -1); + Assert.IsTrue(resultAsMarkdown.IndexOf("Result: 'Success'" + Environment.NewLine) > -1); } [Test] @@ -149,8 +151,8 @@ namespace Umbraco.Tests.Web.HealthChecks var results = new HealthCheckResults(checks); var resultAsMarkdown = results.ResultsAsMarkDown(HealthCheckNotificationVerbosity.Detailed); - Assert.IsFalse(resultAsMarkdown.IndexOf("Result: 'Success'\r\n") > -1); - Assert.IsTrue(resultAsMarkdown.IndexOf("Result: 'Success', Message: 'First check was successful'\r\n") > -1); + Assert.IsFalse(resultAsMarkdown.IndexOf("Result: 'Success'" + Environment.NewLine) > -1); + Assert.IsTrue(resultAsMarkdown.IndexOf("Result: 'Success', Message: 'First check was successful'" + Environment.NewLine) > -1); } } } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Macros/MacroParserTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Macros/MacroParserTests.cs new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Macros/MacroParserTests.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Manifest/ManifestContentAppTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Manifest/ManifestContentAppTests.cs new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Manifest/ManifestContentAppTests.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Manifest/ManifestParserTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Manifest/ManifestParserTests.cs new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Manifest/ManifestParserTests.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Media/ImageSharpImageUrlGeneratorTests.cs similarity index 99% rename from src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Media/ImageSharpImageUrlGeneratorTests.cs index a44d240ea9..febb36145b 100644 --- a/src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Media/ImageSharpImageUrlGeneratorTests.cs @@ -3,10 +3,10 @@ using Umbraco.Core.Models; using Umbraco.Infrastructure.Media; using Umbraco.Web.Models; -namespace Umbraco.Tests.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Media { [TestFixture] - public class ImageProcessorImageUrlGeneratorTest + public class ImageSharpImageUrlGeneratorTests { private const string MediaPath = "/media/1005/img_0671.jpg"; private static readonly ImageUrlGenerationOptions.CropCoordinates Crop = new ImageUrlGenerationOptions.CropCoordinates(0.58729977382575338m, 0.055768992440203169m, 0m, 0.32457553600198386m); diff --git a/src/Umbraco.Tests/Persistence/BulkDataReaderTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/BulkDataReaderTests.cs similarity index 99% rename from src/Umbraco.Tests/Persistence/BulkDataReaderTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/BulkDataReaderTests.cs index c157d66b2c..10926ef20a 100644 --- a/src/Umbraco.Tests/Persistence/BulkDataReaderTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/BulkDataReaderTests.cs @@ -6,7 +6,7 @@ using System.Data.Common; using NUnit.Framework; using Umbraco.Core.Persistence; -namespace Umbraco.Tests.Persistence +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence { /// /// Unit tests for . diff --git a/src/Umbraco.Tests/Persistence/Mappers/ContentMapperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/ContentMapperTest.cs similarity index 57% rename from src/Umbraco.Tests/Persistence/Mappers/ContentMapperTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/ContentMapperTest.cs index 9ad77c0246..7c0ea0d642 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/ContentMapperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/ContentMapperTest.cs @@ -2,37 +2,38 @@ using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Mappers; +using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Mappers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Mappers { [TestFixture] - public class ContentMapperTest : MapperTestBase + public class ContentMapperTest { [Test] public void Can_Map_Id_Property() { - var column = new ContentMapper(MockSqlContext(), CreateMaps()).Map(nameof(Content.Id)); + var column = new ContentMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map(nameof(Content.Id)); Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.Node}].[id]")); } [Test] public void Can_Map_Trashed_Property() { - var column = new ContentMapper(MockSqlContext(), CreateMaps()).Map(nameof(Content.Trashed)); + var column = new ContentMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map(nameof(Content.Trashed)); Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.Node}].[trashed]")); } [Test] public void Can_Map_Published_Property() { - var column = new ContentMapper(MockSqlContext(), CreateMaps()).Map(nameof(Content.Published)); + var column = new ContentMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map(nameof(Content.Published)); Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.Document}].[published]")); } [Test] public void Can_Map_Version_Property() { - var column = new ContentMapper(MockSqlContext(), CreateMaps()).Map(nameof(Content.VersionId)); + var column = new ContentMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map(nameof(Content.VersionId)); Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.ContentVersion}].[id]")); } } diff --git a/src/Umbraco.Tests/Persistence/Mappers/ContentTypeMapperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/ContentTypeMapperTest.cs similarity index 58% rename from src/Umbraco.Tests/Persistence/Mappers/ContentTypeMapperTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/ContentTypeMapperTest.cs index dcd064e862..6666055ed7 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/ContentTypeMapperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/ContentTypeMapperTest.cs @@ -1,17 +1,17 @@ using NUnit.Framework; using Umbraco.Core.Persistence.Mappers; +using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Mappers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Mappers { [TestFixture] - public class ContentTypeMapperTest : MapperTestBase + public class ContentTypeMapperTest { [Test] public void Can_Map_Id_Property() { - // Act - string column = new ContentTypeMapper(MockSqlContext(), CreateMaps()).Map("Id"); + string column = new ContentTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Id"); // Assert Assert.That(column, Is.EqualTo("[umbracoNode].[id]")); @@ -22,7 +22,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new ContentTypeMapper(MockSqlContext(), CreateMaps()).Map("Name"); + string column = new ContentTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Name"); // Assert Assert.That(column, Is.EqualTo("[umbracoNode].[text]")); @@ -33,7 +33,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new ContentTypeMapper(MockSqlContext(), CreateMaps()).Map("Thumbnail"); + string column = new ContentTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Thumbnail"); // Assert Assert.That(column, Is.EqualTo("[cmsContentType].[thumbnail]")); @@ -44,7 +44,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new ContentTypeMapper(MockSqlContext(), CreateMaps()).Map("Description"); + string column = new ContentTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Description"); // Assert Assert.That(column, Is.EqualTo("[cmsContentType].[description]")); diff --git a/src/Umbraco.Tests/Persistence/Mappers/DataTypeMapperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/DataTypeMapperTest.cs similarity index 61% rename from src/Umbraco.Tests/Persistence/Mappers/DataTypeMapperTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/DataTypeMapperTest.cs index 2ae8f755a2..0725528254 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/DataTypeMapperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/DataTypeMapperTest.cs @@ -1,19 +1,18 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Persistence.Mappers; -using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Mappers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Mappers { [TestFixture] - public class DataTypeMapperTest : MapperTestBase + public class DataTypeMapperTest { [Test] public void Can_Map_Id_Property() { - // Act - string column = new DataTypeMapper(MockSqlContext(), CreateMaps()).Map("Id"); + string column = new DataTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Id"); // Assert Assert.That(column, Is.EqualTo("[umbracoNode].[id]")); @@ -24,7 +23,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new DataTypeMapper(MockSqlContext(), CreateMaps()).Map("Key"); + string column = new DataTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Key"); // Assert Assert.That(column, Is.EqualTo("[umbracoNode].[uniqueId]")); @@ -35,7 +34,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new DataTypeMapper(MockSqlContext(), CreateMaps()).Map("DatabaseType"); + string column = new DataTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("DatabaseType"); // Assert Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.DataType}].[dbType]")); @@ -46,7 +45,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new DataTypeMapper(MockSqlContext(), CreateMaps()).Map("EditorAlias"); + string column = new DataTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("EditorAlias"); // Assert Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.DataType}].[propertyEditorAlias]")); diff --git a/src/Umbraco.Tests/Persistence/Mappers/DictionaryMapperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/DictionaryMapperTest.cs similarity index 57% rename from src/Umbraco.Tests/Persistence/Mappers/DictionaryMapperTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/DictionaryMapperTest.cs index cb4e8dc534..a27fc89dac 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/DictionaryMapperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/DictionaryMapperTest.cs @@ -1,18 +1,17 @@ using NUnit.Framework; using Umbraco.Core.Persistence.Mappers; -using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Mappers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Mappers { [TestFixture] - public class DictionaryMapperTest : MapperTestBase + public class DictionaryMapperTest { [Test] public void Can_Map_Id_Property() { - // Act - string column = new DictionaryMapper(MockSqlContext(), CreateMaps()).Map("Id"); + string column = new DictionaryMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Id"); // Assert Assert.That(column, Is.EqualTo("[cmsDictionary].[pk]")); @@ -23,7 +22,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new DictionaryMapper(MockSqlContext(), CreateMaps()).Map("Key"); + string column = new DictionaryMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Key"); // Assert Assert.That(column, Is.EqualTo("[cmsDictionary].[id]")); @@ -34,7 +33,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new DictionaryMapper(MockSqlContext(), CreateMaps()).Map("ItemKey"); + string column = new DictionaryMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("ItemKey"); // Assert Assert.That(column, Is.EqualTo("[cmsDictionary].[key]")); diff --git a/src/Umbraco.Tests/Persistence/Mappers/DictionaryTranslationMapperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/DictionaryTranslationMapperTest.cs similarity index 55% rename from src/Umbraco.Tests/Persistence/Mappers/DictionaryTranslationMapperTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/DictionaryTranslationMapperTest.cs index c40ddb0cdf..c1fbc6ad61 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/DictionaryTranslationMapperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/DictionaryTranslationMapperTest.cs @@ -1,17 +1,18 @@ using NUnit.Framework; using Umbraco.Core.Persistence.Mappers; +using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Mappers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Mappers { [TestFixture] - public class DictionaryTranslationMapperTest : MapperTestBase + public class DictionaryTranslationMapperTest { [Test] public void Can_Map_Key_Property() { // Act - string column = new DictionaryTranslationMapper(MockSqlContext(), CreateMaps()).Map("Key"); + string column = new DictionaryTranslationMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Key"); // Assert Assert.That(column, Is.EqualTo("[cmsLanguageText].[UniqueId]")); @@ -22,7 +23,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new DictionaryTranslationMapper(MockSqlContext(), CreateMaps()).Map("Language"); + string column = new DictionaryTranslationMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Language"); // Assert Assert.That(column, Is.EqualTo("[cmsLanguageText].[languageId]")); @@ -33,7 +34,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new DictionaryTranslationMapper(MockSqlContext(), CreateMaps()).Map("Value"); + string column = new DictionaryTranslationMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Value"); // Assert Assert.That(column, Is.EqualTo("[cmsLanguageText].[value]")); diff --git a/src/Umbraco.Tests/Persistence/Mappers/LanguageMapperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/LanguageMapperTest.cs similarity index 58% rename from src/Umbraco.Tests/Persistence/Mappers/LanguageMapperTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/LanguageMapperTest.cs index 5db8a991d6..382d8c6826 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/LanguageMapperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/LanguageMapperTest.cs @@ -1,18 +1,18 @@ using NUnit.Framework; using Umbraco.Core.Persistence.Mappers; -using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Mappers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Mappers { [TestFixture] - public class LanguageMapperTest : MapperTestBase + public class LanguageMapperTest { [Test] public void Can_Map_Id_Property() { // Act - string column = new LanguageMapper(MockSqlContext(), CreateMaps()).Map("Id"); + string column = new LanguageMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Id"); // Assert Assert.That(column, Is.EqualTo("[umbracoLanguage].[id]")); @@ -23,7 +23,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new LanguageMapper(MockSqlContext(), CreateMaps()).Map("IsoCode"); + string column = new LanguageMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("IsoCode"); // Assert Assert.That(column, Is.EqualTo("[umbracoLanguage].[languageISOCode]")); @@ -33,7 +33,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_CultureName_Property() { // Act - string column = new LanguageMapper(MockSqlContext(), CreateMaps()).Map("CultureName"); + string column = new LanguageMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("CultureName"); // Assert Assert.That(column, Is.EqualTo("[umbracoLanguage].[languageCultureName]")); diff --git a/src/Umbraco.Tests/Persistence/Mappers/MediaMapperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/MediaMapperTest.cs similarity index 54% rename from src/Umbraco.Tests/Persistence/Mappers/MediaMapperTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/MediaMapperTest.cs index 9c7b0729b6..cc7d528c3c 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/MediaMapperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/MediaMapperTest.cs @@ -1,39 +1,39 @@ using NUnit.Framework; using Umbraco.Core; -using Umbraco.Core.Models; using Umbraco.Core.Persistence.Mappers; -using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Tests.TestHelpers; +using MediaModel = Umbraco.Core.Models.Media; -namespace Umbraco.Tests.Persistence.Mappers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Mappers { [TestFixture] - public class MediaMapperTest : MapperTestBase + public class MediaMapperTest { [Test] public void Can_Map_Id_Property() { - var column = new MediaMapper(MockSqlContext(), CreateMaps()).Map(nameof(Media.Id)); + var column = new MediaMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map(nameof(MediaModel.Id)); Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.Node}].[id]")); } [Test] public void Can_Map_Trashed_Property() { - var column = new MediaMapper(MockSqlContext(), CreateMaps()).Map(nameof(Media.Trashed)); + var column = new MediaMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map(nameof(MediaModel.Trashed)); Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.Node}].[trashed]")); } [Test] public void Can_Map_UpdateDate_Property() { - var column = new MediaMapper(MockSqlContext(), CreateMaps()).Map(nameof(Media.UpdateDate)); + var column = new MediaMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map(nameof(MediaModel.UpdateDate)); Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.ContentVersion}].[versionDate]")); } [Test] public void Can_Map_Version_Property() { - var column = new MediaMapper(MockSqlContext(), CreateMaps()).Map(nameof(Media.VersionId)); + var column = new MediaMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map(nameof(MediaModel.VersionId)); Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.ContentVersion}].[id]")); } } diff --git a/src/Umbraco.Tests/Persistence/Mappers/PropertyGroupMapperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/PropertyGroupMapperTest.cs similarity index 57% rename from src/Umbraco.Tests/Persistence/Mappers/PropertyGroupMapperTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/PropertyGroupMapperTest.cs index 780ae482cb..f5fa18e4ee 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/PropertyGroupMapperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/PropertyGroupMapperTest.cs @@ -1,16 +1,17 @@ using NUnit.Framework; using Umbraco.Core.Persistence.Mappers; +using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Mappers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Mappers { [TestFixture] - public class PropertyGroupMapperTest : MapperTestBase + public class PropertyGroupMapperTest { [Test] public void Can_Map_Id_Property() { // Act - string column = new PropertyGroupMapper(MockSqlContext(), CreateMaps()).Map("Id"); + string column = new PropertyGroupMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Id"); // Assert Assert.That(column, Is.EqualTo("[cmsPropertyTypeGroup].[id]")); @@ -20,7 +21,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_SortOrder_Property() { // Act - string column = new PropertyGroupMapper(MockSqlContext(), CreateMaps()).Map("SortOrder"); + string column = new PropertyGroupMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("SortOrder"); // Assert Assert.That(column, Is.EqualTo("[cmsPropertyTypeGroup].[sortorder]")); @@ -30,7 +31,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Name_Property() { // Act - string column = new PropertyGroupMapper(MockSqlContext(), CreateMaps()).Map("Name"); + string column = new PropertyGroupMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Name"); // Assert Assert.That(column, Is.EqualTo("[cmsPropertyTypeGroup].[text]")); diff --git a/src/Umbraco.Tests/Persistence/Mappers/PropertyTypeMapperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/PropertyTypeMapperTest.cs similarity index 60% rename from src/Umbraco.Tests/Persistence/Mappers/PropertyTypeMapperTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/PropertyTypeMapperTest.cs index ab76fa211b..ba2d40feab 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/PropertyTypeMapperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/PropertyTypeMapperTest.cs @@ -1,18 +1,18 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Persistence.Mappers; -using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Mappers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Mappers { [TestFixture] - public class PropertyTypeMapperTest : MapperTestBase + public class PropertyTypeMapperTest { [Test] public void Can_Map_Id_Property() { // Act - string column = new PropertyTypeMapper(MockSqlContext(), CreateMaps()).Map("Id"); + string column = new PropertyTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Id"); // Assert Assert.That(column, Is.EqualTo("[cmsPropertyType].[id]")); @@ -22,7 +22,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Alias_Property() { // Act - string column = new PropertyTypeMapper(MockSqlContext(), CreateMaps()).Map("Alias"); + string column = new PropertyTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Alias"); // Assert Assert.That(column, Is.EqualTo("[cmsPropertyType].[Alias]")); @@ -32,7 +32,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_DataTypeDefinitionId_Property() { // Act - string column = new PropertyTypeMapper(MockSqlContext(), CreateMaps()).Map("DataTypeId"); + string column = new PropertyTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("DataTypeId"); // Assert Assert.That(column, Is.EqualTo("[cmsPropertyType].[dataTypeId]")); @@ -42,7 +42,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_SortOrder_Property() { // Act - string column = new PropertyTypeMapper(MockSqlContext(), CreateMaps()).Map("SortOrder"); + string column = new PropertyTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("SortOrder"); // Assert Assert.That(column, Is.EqualTo("[cmsPropertyType].[sortOrder]")); @@ -52,7 +52,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_PropertyEditorAlias_Property() { // Act - string column = new PropertyTypeMapper(MockSqlContext(), CreateMaps()).Map("PropertyEditorAlias"); + string column = new PropertyTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("PropertyEditorAlias"); // Assert Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.DataType}].[propertyEditorAlias]")); @@ -62,7 +62,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_DataTypeDatabaseType_Property() { // Act - string column = new PropertyTypeMapper(MockSqlContext(), CreateMaps()).Map("ValueStorageType"); + string column = new PropertyTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("ValueStorageType"); // Assert Assert.That(column, Is.EqualTo($"[{Constants.DatabaseSchema.Tables.DataType}].[dbType]")); diff --git a/src/Umbraco.Tests/Persistence/Mappers/RelationMapperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/RelationMapperTest.cs similarity index 59% rename from src/Umbraco.Tests/Persistence/Mappers/RelationMapperTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/RelationMapperTest.cs index 630c263924..4f1b4a7944 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/RelationMapperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/RelationMapperTest.cs @@ -1,17 +1,17 @@ using NUnit.Framework; using Umbraco.Core.Persistence.Mappers; -using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Mappers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Mappers { [TestFixture] - public class RelationMapperTest : MapperTestBase + public class RelationMapperTest { [Test] public void Can_Map_Id_Property() { // Act - string column = new RelationMapper(MockSqlContext(), CreateMaps()).Map("Id"); + string column = new RelationMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Id"); // Assert Assert.That(column, Is.EqualTo("[umbracoRelation].[id]")); @@ -21,7 +21,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_ChildId_Property() { // Act - string column = new RelationMapper(MockSqlContext(), CreateMaps()).Map("ChildId"); + string column = new RelationMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("ChildId"); // Assert Assert.That(column, Is.EqualTo("[umbracoRelation].[childId]")); @@ -31,7 +31,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Datetime_Property() { // Act - string column = new RelationMapper(MockSqlContext(), CreateMaps()).Map("CreateDate"); + string column = new RelationMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("CreateDate"); // Assert Assert.That(column, Is.EqualTo("[umbracoRelation].[datetime]")); @@ -41,7 +41,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Comment_Property() { // Act - string column = new RelationMapper(MockSqlContext(), CreateMaps()).Map("Comment"); + string column = new RelationMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Comment"); // Assert Assert.That(column, Is.EqualTo("[umbracoRelation].[comment]")); @@ -51,7 +51,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_RelationType_Property() { // Act - string column = new RelationMapper(MockSqlContext(), CreateMaps()).Map("RelationTypeId"); + string column = new RelationMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("RelationTypeId"); // Assert Assert.That(column, Is.EqualTo("[umbracoRelation].[relType]")); diff --git a/src/Umbraco.Tests/Persistence/Mappers/RelationTypeMapperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/RelationTypeMapperTest.cs similarity index 58% rename from src/Umbraco.Tests/Persistence/Mappers/RelationTypeMapperTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/RelationTypeMapperTest.cs index 32e4f307c9..e17d6905ac 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/RelationTypeMapperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Mappers/RelationTypeMapperTest.cs @@ -1,17 +1,17 @@ using NUnit.Framework; using Umbraco.Core.Persistence.Mappers; -using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Mappers +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Mappers { [TestFixture] - public class RelationTypeMapperTest : MapperTestBase + public class RelationTypeMapperTest { [Test] public void Can_Map_Id_Property() { // Act - string column = new RelationTypeMapper(MockSqlContext(), CreateMaps()).Map("Id"); + string column = new RelationTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Id"); // Assert Assert.That(column, Is.EqualTo("[umbracoRelationType].[id]")); @@ -21,7 +21,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Alias_Property() { // Act - string column = new RelationTypeMapper(MockSqlContext(), CreateMaps()).Map("Alias"); + string column = new RelationTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("Alias"); // Assert Assert.That(column, Is.EqualTo("[umbracoRelationType].[alias]")); @@ -32,7 +32,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new RelationTypeMapper(MockSqlContext(), CreateMaps()).Map("ChildObjectType"); + string column = new RelationTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("ChildObjectType"); // Assert Assert.That(column, Is.EqualTo("[umbracoRelationType].[childObjectType]")); @@ -43,7 +43,7 @@ namespace Umbraco.Tests.Persistence.Mappers { // Act - string column = new RelationTypeMapper(MockSqlContext(), CreateMaps()).Map("IsBidirectional"); + string column = new RelationTypeMapper(TestHelper.GetMockSqlContext(), TestHelper.CreateMaps()).Map("IsBidirectional"); // Assert Assert.That(column, Is.EqualTo("[umbracoRelationType].[dual]")); diff --git a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlExtensionsTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoSqlExtensionsTests.cs similarity index 98% rename from src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlExtensionsTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoSqlExtensionsTests.cs index 373de9e654..9e9b148bb6 100644 --- a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlExtensionsTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoSqlExtensionsTests.cs @@ -7,10 +7,10 @@ using Umbraco.Core.Persistence.Dtos; using Umbraco.Tests.TestHelpers; using static Umbraco.Core.Persistence.SqlExtensionsStatics; -namespace Umbraco.Tests.Persistence.NPocoTests +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.NPocoTests { [TestFixture] - public class NPocoSqlExtensionsTests : BaseUsingSqlCeSyntax + public class NPocoSqlExtensionsTests : BaseUsingSqlSyntax { [Test] public void WhereTest() diff --git a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlTemplateTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoSqlTemplateTests.cs similarity index 77% rename from src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlTemplateTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoSqlTemplateTests.cs index f2bbfaea21..0367571d61 100644 --- a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlTemplateTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoSqlTemplateTests.cs @@ -4,11 +4,11 @@ using NPoco; using NUnit.Framework; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Mappers; -using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core; -using Umbraco.Persistance.SqlCe; +using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.NPocoTests +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.NPocoTests { [TestFixture] public class NPocoSqlTemplateTests @@ -16,7 +16,7 @@ namespace Umbraco.Tests.Persistence.NPocoTests [Test] public void SqlTemplates() { - var sqlContext = new SqlContext(new SqlCeSyntaxProvider(), DatabaseType.SQLCe, Mock.Of()); + var sqlContext = new SqlContext(new SqlServerSyntaxProvider(), DatabaseType.SqlServer2012, Mock.Of()); var sqlTemplates = new SqlTemplates(sqlContext); // this can be used for queries that we know we'll use a *lot* and @@ -39,13 +39,13 @@ namespace Umbraco.Tests.Persistence.NPocoTests var mappers = new NPoco.MapperCollection { new PocoMapper() }; var factory = new FluentPocoDataFactory((type, iPocoDataFactory) => new PocoDataBuilder(type, mappers).Init()); - var sqlContext = new SqlContext(new SqlCeSyntaxProvider(), DatabaseType.SQLCe, factory); + var sqlContext = new SqlContext(new SqlServerSyntaxProvider(), DatabaseType.SQLCe, factory); var sqlTemplates = new SqlTemplates(sqlContext); const string sqlBase = "SELECT [zbThing1].[id] AS [Id], [zbThing1].[name] AS [Name] FROM [zbThing1] WHERE "; - var template = sqlTemplates.Get("sql1", s => s.Select().From() - .Where(x => x.Name == SqlTemplate.Arg("value"))); + var template = sqlTemplates.Get("sql1", s => s.Select().From() + .Where(x => x.Name == SqlTemplate.Arg("value"))); var sql = template.Sql("foo"); Assert.AreEqual(sqlBase + "(([zbThing1].[name] = @0))", sql.SQL.NoCrLf()); @@ -57,8 +57,8 @@ namespace Umbraco.Tests.Persistence.NPocoTests Assert.AreEqual(1, sql.Arguments.Length); Assert.AreEqual(123, sql.Arguments[0]); - template = sqlTemplates.Get("sql2", s => s.Select().From() - .Where(x => x.Name == SqlTemplate.Arg("value"))); + template = sqlTemplates.Get("sql2", s => s.Select().From() + .Where(x => x.Name == SqlTemplate.Arg("value"))); sql = template.Sql(new { value = "foo" }); Assert.AreEqual(sqlBase + "(([zbThing1].[name] = @0))", sql.SQL.NoCrLf()); @@ -75,8 +75,8 @@ namespace Umbraco.Tests.Persistence.NPocoTests var i = 666; - template = sqlTemplates.Get("sql3", s => s.Select().From() - .Where(x => x.Id == i)); + template = sqlTemplates.Get("sql3", s => s.Select().From() + .Where(x => x.Id == i)); sql = template.Sql("foo"); Assert.AreEqual(sqlBase + "(([zbThing1].[id] = @0))", sql.SQL.NoCrLf()); @@ -91,8 +91,8 @@ namespace Umbraco.Tests.Persistence.NPocoTests // but we cannot name them, because the arg name is the value of "i" // so we have to explicitely create the argument - template = sqlTemplates.Get("sql4", s => s.Select().From() - .Where(x => x.Id == SqlTemplate.Arg("i"))); + template = sqlTemplates.Get("sql4", s => s.Select().From() + .Where(x => x.Id == SqlTemplate.Arg("i"))); sql = template.Sql("foo"); Assert.AreEqual(sqlBase + "(([zbThing1].[id] = @0))", sql.SQL.NoCrLf()); @@ -121,17 +121,17 @@ namespace Umbraco.Tests.Persistence.NPocoTests // now with more arguments - template = sqlTemplates.Get("sql4a", s => s.Select().From() - .Where(x => x.Id == SqlTemplate.Arg("i") && x.Name == SqlTemplate.Arg("name"))); + template = sqlTemplates.Get("sql4a", s => s.Select().From() + .Where(x => x.Id == SqlTemplate.Arg("i") && x.Name == SqlTemplate.Arg("name"))); sql = template.Sql(0, 1); Assert.AreEqual(sqlBase + "((([zbThing1].[id] = @0) AND ([zbThing1].[name] = @1)))", sql.SQL.NoCrLf()); Assert.AreEqual(2, sql.Arguments.Length); Assert.AreEqual(0, sql.Arguments[0]); Assert.AreEqual(1, sql.Arguments[1]); - template = sqlTemplates.Get("sql4b", s => s.Select().From() - .Where(x => x.Id == SqlTemplate.Arg("i")) - .Where(x => x.Name == SqlTemplate.Arg("name"))); + template = sqlTemplates.Get("sql4b", s => s.Select().From() + .Where(x => x.Id == SqlTemplate.Arg("i")) + .Where(x => x.Name == SqlTemplate.Arg("name"))); sql = template.Sql(0, 1); Assert.AreEqual(sqlBase + "(([zbThing1].[id] = @0)) AND (([zbThing1].[name] = @1))", sql.SQL.NoCrLf()); Assert.AreEqual(2, sql.Arguments.Length); @@ -140,8 +140,8 @@ namespace Umbraco.Tests.Persistence.NPocoTests // works, magic - template = sqlTemplates.Get("sql5", s => s.Select().From() - .WhereIn(x => x.Id, SqlTemplate.ArgIn("i"))); + template = sqlTemplates.Get("sql5", s => s.Select().From() + .WhereIn(x => x.Id, SqlTemplate.ArgIn("i"))); sql = template.Sql("foo"); Assert.AreEqual(sqlBase + "([zbThing1].[id] IN (@0))", sql.SQL.NoCrLf()); @@ -155,9 +155,9 @@ namespace Umbraco.Tests.Persistence.NPocoTests Assert.AreEqual(2, sql.Arguments[1]); Assert.AreEqual(3, sql.Arguments[2]); - template = sqlTemplates.Get("sql5a", s => s.Select().From() - .WhereIn(x => x.Id, SqlTemplate.ArgIn("i")) - .Where(x => x.Name == SqlTemplate.Arg("name"))); + template = sqlTemplates.Get("sql5a", s => s.Select().From() + .WhereIn(x => x.Id, SqlTemplate.ArgIn("i")) + .Where(x => x.Name == SqlTemplate.Arg("name"))); sql = template.Sql("foo", "bar"); Assert.AreEqual(sqlBase + "([zbThing1].[id] IN (@0)) AND (([zbThing1].[name] = @1))", sql.SQL.NoCrLf()); @@ -179,7 +179,7 @@ namespace Umbraco.Tests.Persistence.NPocoTests // more fun... - template = sqlTemplates.Get("sql6", s => s.Select().From() + template = sqlTemplates.Get("sql6", s => s.Select().From() // do NOT do this, this is NOT a visited expression //.Append(" AND whatever=@0", SqlTemplate.Arg("j")) @@ -201,5 +201,17 @@ namespace Umbraco.Tests.Persistence.NPocoTests Assert.AreEqual(3, sql.Arguments[2]); Assert.AreEqual("oops", sql.Arguments[3]); } + + [TableName("zbThing1")] + [PrimaryKey("id", AutoIncrement = false)] + [ExplicitColumns] + public class Thing1Dto + { + [Column("id")] + public int Id { get; set; } + + [Column("name")] + public string Name { get; set; } + } } } diff --git a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoSqlTests.cs similarity index 98% rename from src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoSqlTests.cs index a04984eb64..80408bb211 100644 --- a/src/Umbraco.Tests/Persistence/NPocoTests/NPocoSqlTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/NPocoTests/NPocoSqlTests.cs @@ -1,19 +1,19 @@ using System; using System.Diagnostics; +using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.Persistence.Querying; using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.NPocoTests +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.NPocoTests { [TestFixture] - public class NPocoSqlTests : BaseUsingSqlCeSyntax + public class NPocoSqlTests : BaseUsingSqlSyntax { - //x => - [Test] public void Where_Clause_With_Starts_With_Additional_Parameters() { diff --git a/src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs similarity index 98% rename from src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs index 9745caa8c9..66253de575 100644 --- a/src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs @@ -1,17 +1,15 @@ using System; using System.Diagnostics; -using NPoco; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Querying +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Querying { [TestFixture] - public class ContentTypeRepositorySqlClausesTest : BaseUsingSqlCeSyntax + public class ContentTypeRepositorySqlClausesTest : BaseUsingSqlSyntax { [Test] public void Can_Verify_Base_Clause() diff --git a/src/Umbraco.Tests/Persistence/Querying/DataTypeDefinitionRepositorySqlClausesTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/DataTypeDefinitionRepositorySqlClausesTest.cs similarity index 93% rename from src/Umbraco.Tests/Persistence/Querying/DataTypeDefinitionRepositorySqlClausesTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/DataTypeDefinitionRepositorySqlClausesTest.cs index 53bc6e5c68..708e7cac70 100644 --- a/src/Umbraco.Tests/Persistence/Querying/DataTypeDefinitionRepositorySqlClausesTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/DataTypeDefinitionRepositorySqlClausesTest.cs @@ -7,10 +7,10 @@ using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Querying +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Querying { [TestFixture] - public class DataTypeDefinitionRepositorySqlClausesTest : BaseUsingSqlCeSyntax + public class DataTypeDefinitionRepositorySqlClausesTest : BaseUsingSqlSyntax { [Test] public void Can_Verify_Base_Clause() diff --git a/src/Umbraco.Tests/Persistence/Querying/ExpressionTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/ExpressionTests.cs similarity index 98% rename from src/Umbraco.Tests/Persistence/Querying/ExpressionTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/ExpressionTests.cs index 3da803505f..38a2addad6 100644 --- a/src/Umbraco.Tests/Persistence/Querying/ExpressionTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/ExpressionTests.cs @@ -2,9 +2,7 @@ using System.Diagnostics; using System.Linq.Expressions; using Moq; -using NPoco; using NUnit.Framework; -using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence; @@ -17,12 +15,11 @@ using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Core.Strings; -using Umbraco.Persistance.SqlCe; -namespace Umbraco.Tests.Persistence.Querying +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Querying { [TestFixture] - public class ExpressionTests : BaseUsingSqlCeSyntax + public class ExpressionTests : BaseUsingSqlSyntax { [Test] public void Equals_Claus_With_Two_Entity_Values() @@ -154,7 +151,7 @@ namespace Umbraco.Tests.Persistence.Querying [Test] public void Equals_Method_For_Value_Gets_Escaped() { - var sqlSyntax = new SqlCeSyntaxProvider(); + var sqlSyntax = new SqlServerSyntaxProvider(); Expression> predicate = user => user.Username.Equals("hello@world.com"); var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor(SqlContext.SqlSyntax, Mappers); var result = modelToSqlExpressionHelper.Visit(predicate); diff --git a/src/Umbraco.Tests/Persistence/Querying/MediaRepositorySqlClausesTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/MediaRepositorySqlClausesTest.cs similarity index 92% rename from src/Umbraco.Tests/Persistence/Querying/MediaRepositorySqlClausesTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/MediaRepositorySqlClausesTest.cs index 8ff0dd2a0d..8c26f6a06b 100644 --- a/src/Umbraco.Tests/Persistence/Querying/MediaRepositorySqlClausesTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/MediaRepositorySqlClausesTest.cs @@ -7,10 +7,10 @@ using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Querying +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Querying { [TestFixture] - public class MediaRepositorySqlClausesTest : BaseUsingSqlCeSyntax + public class MediaRepositorySqlClausesTest : BaseUsingSqlSyntax { [Test] public void Can_Verify_Base_Clause() diff --git a/src/Umbraco.Tests/Persistence/Querying/MediaTypeRepositorySqlClausesTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/MediaTypeRepositorySqlClausesTest.cs similarity index 94% rename from src/Umbraco.Tests/Persistence/Querying/MediaTypeRepositorySqlClausesTest.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/MediaTypeRepositorySqlClausesTest.cs index bcb62ec770..f28540454d 100644 --- a/src/Umbraco.Tests/Persistence/Querying/MediaTypeRepositorySqlClausesTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/MediaTypeRepositorySqlClausesTest.cs @@ -7,10 +7,10 @@ using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Querying +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Querying { [TestFixture] - public class MediaTypeRepositorySqlClausesTest : BaseUsingSqlCeSyntax + public class MediaTypeRepositorySqlClausesTest : BaseUsingSqlSyntax { [Test] public void Can_Verify_Base_Clause() diff --git a/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/QueryBuilderTests.cs similarity index 96% rename from src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs rename to src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/QueryBuilderTests.cs index ca6b4cd5f0..f4b8c2b250 100644 --- a/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Persistence/Querying/QueryBuilderTests.cs @@ -7,10 +7,10 @@ using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.Persistence.Querying; using Umbraco.Tests.TestHelpers; -namespace Umbraco.Tests.Persistence.Querying +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Querying { [TestFixture] - public class QueryBuilderTests : BaseUsingSqlCeSyntax + public class QueryBuilderTests : BaseUsingSqlSyntax { [Test] public void Can_Build_StartsWith_Query_For_IContent() diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/LocalizedTextServiceTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/LocalizedTextServiceTests.cs index d413481475..dc857d2d5d 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/LocalizedTextServiceTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/LocalizedTextServiceTests.cs @@ -8,7 +8,7 @@ using Microsoft.Extensions.Logging.Abstractions; using NUnit.Framework; using Umbraco.Core.Services.Implement; -namespace Umbraco.Tests.Services +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Services { [TestFixture] public class LocalizedTextServiceTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/PropertyValidationServiceTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/PropertyValidationServiceTests.cs index 8a7bad3d8c..3acfce1781 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/PropertyValidationServiceTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/PropertyValidationServiceTests.cs @@ -9,7 +9,7 @@ using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Web.PropertyEditors; -namespace Umbraco.Tests.Services +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Services { [TestFixture] public class PropertyValidationServiceTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Tests.Common/Builders/StylesheetBuilderTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Tests.Common/Builders/StylesheetBuilderTests.cs index a9104b5dd4..c770860b9c 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Tests.Common/Builders/StylesheetBuilderTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Tests.Common/Builders/StylesheetBuilderTests.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using NUnit.Framework; using Umbraco.Core.Routing; using Umbraco.Tests.Common.Builders; @@ -24,7 +25,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Tests.Common.Builders .Build(); // Assert - Assert.AreEqual("\\css\\styles.css", stylesheet.Path); + Assert.AreEqual(Path.DirectorySeparatorChar + Path.Combine("css", "styles.css"), stylesheet.Path); Assert.AreEqual(testContent, stylesheet.Content); } } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/ContentControllerUnitTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/ContentControllerUnitTests.cs index 2f76db452a..3df5f76da5 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/ContentControllerUnitTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/ContentControllerUnitTests.cs @@ -8,7 +8,7 @@ using Umbraco.Core.Services; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.Web.Controllers +namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Controllers { [TestFixture] public class ContentControllerUnitTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/MediaControllerUnitTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/MediaControllerUnitTests.cs index 91305e463c..2f692ade85 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/MediaControllerUnitTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/MediaControllerUnitTests.cs @@ -10,7 +10,7 @@ using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.Common.Exceptions; -namespace Umbraco.Tests.Web.Controllers +namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Controllers { [TestFixture] public class MediaControllerUnitTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/UsersControllerUnitTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/UsersControllerUnitTests.cs index 97a90be908..b04a5ff158 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/UsersControllerUnitTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/UsersControllerUnitTests.cs @@ -8,7 +8,7 @@ using Umbraco.Tests.UnitTests.AutoFixture; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.Common.Exceptions; -namespace Umbraco.Tests.Web.Controllers +namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Controllers { [TestFixture] public class UsersControllerUnitTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Extensions/ModelStateExtensionsTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Extensions/ModelStateExtensionsTests.cs index 9497827989..01dad1eebf 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Extensions/ModelStateExtensionsTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Extensions/ModelStateExtensionsTests.cs @@ -6,7 +6,7 @@ using NUnit.Framework; using Umbraco.Core.Services; using Umbraco.Extensions; -namespace Umbraco.Tests.Web.Validation +namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Extensions { [TestFixture] public class ModelStateExtensionsTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs index 2c0c91c282..295ece927d 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs @@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NUnit.Framework; +using Umbraco.Web.BackOffice.PropertyEditors.Validation; using Umbraco.Web.PropertyEditors.Validation; namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Filters diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttributeTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttributeTests.cs index 5c186c890c..1ec91d2737 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttributeTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttributeTests.cs @@ -15,7 +15,7 @@ using Umbraco.Web.Actions; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Models.ContentEditing; -namespace Umbraco.Tests.Web.Controllers +namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Filters { [TestFixture] public class FilterAllowedOutgoingContentAttributeTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/ContentModelSerializationTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/ContentModelSerializationTests.cs index 0c7908de9e..eb8b2f8a23 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/ContentModelSerializationTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/ContentModelSerializationTests.cs @@ -6,7 +6,7 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Web.Models.ContentEditing; -namespace Umbraco.Tests.Web.AngularIntegration +namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common.AngularIntegration { [TestFixture] public class ContentModelSerializationTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/JsInitializationTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/JsInitializationTests.cs index f081d0f203..f082ba5d76 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/JsInitializationTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/JsInitializationTests.cs @@ -2,7 +2,7 @@ using Umbraco.Core; using Umbraco.Web.WebAssets; -namespace Umbraco.Tests.Web.AngularIntegration +namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common.AngularIntegration { [TestFixture] public class JsInitializationTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/ServerVariablesParserTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/ServerVariablesParserTests.cs index b0eba4c382..0663c423d8 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/ServerVariablesParserTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/AngularIntegration/ServerVariablesParserTests.cs @@ -3,7 +3,7 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Web.WebAssets; -namespace Umbraco.Tests.Web.AngularIntegration +namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common.AngularIntegration { [TestFixture] public class ServerVariablesParserTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/FileNameTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/FileNameTests.cs index e7cf097dd5..bee0b8bf15 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/FileNameTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/FileNameTests.cs @@ -48,7 +48,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common var viewResult = await sut.Index() as ViewResult; var fileName = GetViewName(viewResult, Path.DirectorySeparatorChar.ToString()); - var views = GetUiFiles(new[] { "Umbraco", "UmbracoInstall" }); + var views = GetUiFiles(new[] { "umbraco", "UmbracoInstall" }); Assert.True(views.Contains(fileName), $"Expected {fileName} to exist, but it didn't"); } @@ -63,7 +63,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common var viewResult = sut.Index() as ViewResult; var fileName = GetViewName(viewResult); - var views = GetUiFiles(new[] { "Umbraco", "UmbracoBackOffice" }); + var views = GetUiFiles(new[] { "umbraco", "UmbracoBackOffice" }); Assert.True(views.Contains(fileName), $"Expected {fileName} to exist, but it didn't"); } @@ -85,7 +85,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common var viewResult = await sut.Default() as ViewResult; var fileName = GetViewName(viewResult); - var views = GetUiFiles(new[] { "Umbraco", "UmbracoBackOffice" }); + var views = GetUiFiles(new[] { "umbraco", "UmbracoBackOffice" }); Assert.True(views.Contains(fileName), $"Expected {fileName} to exist, but it didn't"); } @@ -94,7 +94,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common [Test] public void LanguageFilesAreLowercase() { - var files = GetUiFiles(new[] { "Umbraco", "config", "lang" }); + var files = GetUiFiles(new[] { "umbraco", "config", "lang" }); foreach (var fileName in files) { Assert.AreEqual(fileName.ToLower(), fileName, diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/ImageCropperTest.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/ImageCropperTest.cs index cf91550fe5..417880f476 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/ImageCropperTest.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/ImageCropperTest.cs @@ -11,7 +11,7 @@ using Umbraco.Core.Media; using Umbraco.Extensions; using System.Collections.Generic; -namespace Umbraco.Tests.PropertyEditors +namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common { [TestFixture] diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroParserTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroParserTests.cs index 1d9e9012e0..80a25d7fc5 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroParserTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroParserTests.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using NUnit.Framework; using Umbraco.Web.Macros; -namespace Umbraco.Tests.Macros +namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common.Macros { [TestFixture] public class MacroParserTests @@ -323,7 +323,7 @@ test""> Macro alias: Map -

asdfasdf

".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty)); +

asdfasdf

".NoCrLf(), result.NoCrLf()); } [Test] diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroTests.cs index 9a1b0b1dd2..9bb4e6e54a 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Macros/MacroTests.cs @@ -2,7 +2,7 @@ using Umbraco.Core.Cache; using Umbraco.Web.Macros; -namespace Umbraco.Tests.Macros +namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common.Macros { [TestFixture] public class MacroTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/ModelBinders/ContentModelBinderTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/ModelBinders/ContentModelBinderTests.cs index 0ad8e2c421..b414e49e95 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/ModelBinders/ContentModelBinderTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/ModelBinders/ContentModelBinderTests.cs @@ -45,17 +45,18 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common.ModelBinders } [Test] - public void Does_Not_Bind_Model_When_Source_Type_Matches_Model_Type() + public void BindModel_Returns_If_Same_Type() { // Arrange - var bindingContext = CreateBindingContext(typeof(ContentModel), source: new ContentModel(CreatePublishedContent())); + var content = new ContentModel(CreatePublishedContent()); + var bindingContext = CreateBindingContext(typeof(ContentModel), source: content); var binder = new ContentModelBinder(); // Act binder.BindModelAsync(bindingContext); // Assert - Assert.False(bindingContext.Result.IsModelSet); + Assert.AreSame(content, bindingContext.Result.Model); } [Test] diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/ModelBinders/RenderModelBinderTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/ModelBinders/RenderModelBinderTests.cs new file mode 100644 index 0000000000..501c10551d --- /dev/null +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/ModelBinders/RenderModelBinderTests.cs @@ -0,0 +1,175 @@ +using System; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.AspNetCore.Routing; +using Moq; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Web.Common.ModelBinders; +using Umbraco.Web.Models; + +namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common.ModelBinders +{ + [TestFixture] + public class RenderModelBinderTests + { + private ContentModelBinder _contentModelBinder; + [SetUp] + public void SetUp() + { + _contentModelBinder = new ContentModelBinder(); + } + + [Test] + [TestCase(typeof(IPublishedContent), false)] + [TestCase(typeof(ContentModel), false)] + [TestCase(typeof(MyContent), false)] + [TestCase(typeof(ContentModel), false)] + [TestCase(typeof(MyOtherContent), true)] + [TestCase(typeof(MyCustomContentModel), true)] + [TestCase(typeof(IContentModel), true)] + public void Returns_Binder_For_IPublishedContent_And_IRenderModel(Type testType, bool expectNull) + { + var binderProvider = new ContentModelBinderProvider(); + var contextMock = new Mock(); + contextMock.Setup(x => x.Metadata).Returns(new EmptyModelMetadataProvider().GetMetadataForType(testType)); + + var found = binderProvider.GetBinder(contextMock.Object); + if (expectNull) + { + Assert.IsNull(found); + } + else + { + Assert.IsNotNull(found); + } + } + + [Test] + public void BindModel_Null_Source_Returns_Null() + { + var bindingContext = new DefaultModelBindingContext(); + _contentModelBinder.BindModelAsync(bindingContext, null, typeof(MyContent)); + Assert.IsNull(bindingContext.Result.Model); + } + + [Test] + public void BindModel_Returns_If_Same_Type() + { + var content = new MyContent(Mock.Of()); + var bindingContext = new DefaultModelBindingContext(); + + _contentModelBinder.BindModelAsync(bindingContext, content, typeof(MyContent)); + + Assert.AreSame(content, bindingContext.Result.Model); + } + + [Test] + public void BindModel_RenderModel_To_IPublishedContent() + { + var content = new MyContent(Mock.Of()); + var renderModel = new ContentModel(content); + + var bindingContext = new DefaultModelBindingContext(); + _contentModelBinder.BindModelAsync(bindingContext, renderModel, typeof(IPublishedContent)); + + Assert.AreSame(content, bindingContext.Result.Model); + } + + [Test] + public void BindModel_IPublishedContent_To_RenderModel() + { + var content = new MyContent(Mock.Of()); + var bindingContext = new DefaultModelBindingContext(); + + _contentModelBinder.BindModelAsync(bindingContext, content, typeof(ContentModel)); + var bound = (IContentModel) bindingContext.Result.Model; + + Assert.AreSame(content, bound.Content); + } + + [Test] + public void BindModel_IPublishedContent_To_Generic_RenderModel() + { + var content = new MyContent(Mock.Of()); + var bindingContext = new DefaultModelBindingContext(); + + _contentModelBinder.BindModelAsync(bindingContext, content, typeof(ContentModel)); + var bound = (IContentModel) bindingContext.Result.Model; + + Assert.AreSame(content, bound.Content); + } + + [Test] + public void No_DataToken_Returns_Null() + { + var content = new MyContent(Mock.Of()); + var bindingContext = CreateBindingContext(typeof(ContentModel), false, content); + + _contentModelBinder.BindModelAsync(bindingContext); + + Assert.IsNull(bindingContext.Result.Model); + } + + [Test] + public void Invalid_DataToken_Model_Type_Returns_Null() + { + var bindingContext = CreateBindingContext(typeof(IPublishedContent), source: "Hello"); + _contentModelBinder.BindModelAsync(bindingContext); + Assert.IsNull(bindingContext.Result.Model); + } + + [Test] + public void IPublishedContent_DataToken_Model_Type_Uses_DefaultImplementation() + { + var content = new MyContent(Mock.Of()); + var bindingContext = CreateBindingContext(typeof(MyContent), source: content); + + _contentModelBinder.BindModelAsync(bindingContext); + + Assert.AreEqual(content, bindingContext.Result.Model); + } + + private ModelBindingContext CreateBindingContext(Type modelType, bool withUmbracoDataToken = true, object source = null) + { + var httpContext = new DefaultHttpContext(); + var routeData = new RouteData(); + if (withUmbracoDataToken) + routeData.DataTokens.Add(Constants.Web.UmbracoDataToken, source); + + var actionContext = new ActionContext(httpContext, routeData, new ActionDescriptor()); + var metadataProvider = new EmptyModelMetadataProvider(); + var routeValueDictionary = new RouteValueDictionary(); + var valueProvider = new RouteValueProvider(BindingSource.Path, routeValueDictionary); + return new DefaultModelBindingContext + { + ActionContext = actionContext, + ModelMetadata = metadataProvider.GetMetadataForType(modelType), + ModelName = modelType.Name, + ValueProvider = valueProvider, + }; + } + + public class MyCustomContentModel : ContentModel + { + public MyCustomContentModel(IPublishedContent content) + : base(content) + { } + } + + public class MyOtherContent + { + + } + + public class MyContent : PublishedContentWrapped + { + public MyContent(IPublishedContent content) : base(content) + { + } + } + } +} diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Views/UmbracoViewPageTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Views/UmbracoViewPageTests.cs new file mode 100644 index 0000000000..3b52d0701e --- /dev/null +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Common/Views/UmbracoViewPageTests.cs @@ -0,0 +1,350 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using NUnit.Framework; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Web.Common.AspNetCore; +using Umbraco.Web.Common.ModelBinders; +using Umbraco.Web.Models; + +namespace Umbraco.Tests.UnitTests.Umbraco.Web.Common.Views +{ + [TestFixture] + public class UmbracoViewPageTests + { + #region RenderModel To ... + [Test] + public void RenderModel_To_RenderModel() + { + var content = new ContentType1(null); + var model = new ContentModel(content); + var view = new RenderModelTestPage(); + var viewData = GetViewDataDictionary(model); + view.ViewData = viewData; + + Assert.AreSame(model, view.Model); + } + + [Test] + public void RenderModel_ContentType1_To_ContentType1() + { + var content = new ContentType1(null); + var view = new ContentType1TestPage(); + var viewData = GetViewDataDictionary(content); + + view.ViewData = viewData; + + Assert.IsInstanceOf(view.Model); + } + + [Test] + public void RenderModel_ContentType2_To_ContentType1() + { + var content = new ContentType2(null); + var view = new ContentType1TestPage(); + + var viewData = GetViewDataDictionary(content); + view.ViewData = viewData; + + Assert.IsInstanceOf(view.Model); + } + + [Test] + public void RenderModel_ContentType1_To_ContentType2() + { + var content = new ContentType1(null); + var model = new ContentModel(content); + var view = new ContentType2TestPage(); + var viewData = GetViewDataDictionary(model); + + Assert.ThrowsAsync(async () => await view.SetViewDataAsyncX(viewData)); + } + + [Test] + public void RenderModel_ContentType1_To_RenderModelOf_ContentType1() + { + var content = new ContentType1(null); + var model = new ContentModel(content); + var view = new RenderModelOfContentType1TestPage(); + var viewData = GetViewDataDictionary>(model); + + view.ViewData = viewData; + + Assert.IsInstanceOf>(view.Model); + Assert.IsInstanceOf(view.Model.Content); + } + + [Test] + public void RenderModel_ContentType2_To_RenderModelOf_ContentType1() + { + var content = new ContentType2(null); + var model = new ContentModel(content); + var view = new RenderModelOfContentType1TestPage(); + var viewData = GetViewDataDictionary>(model); + view.ViewData = viewData; + + Assert.IsInstanceOf>(view.Model); + Assert.IsInstanceOf(view.Model.Content); + } + + [Test] + public void RenderModel_ContentType1_To_RenderModelOf_ContentType2() + { + var content = new ContentType1(null); + var model = new ContentModel(content); + var view = new RenderModelOfContentType2TestPage(); + var viewData = GetViewDataDictionary(model); + + Assert.ThrowsAsync(async () => await view.SetViewDataAsyncX(viewData)); + } + + #endregion + + #region RenderModelOf To ... + + [Test] + public void RenderModelOf_ContentType1_To_RenderModel() + { + var content = new ContentType1(null); + var model = new ContentModel(content); + var view = new RenderModelTestPage(); + var viewData = GetViewDataDictionary(model); + + view.ViewData = viewData; + + Assert.AreSame(model, view.Model); + } + + [Test] + public async Task RenderModelOf_ContentType1_To_ContentType1() + { + var content = new ContentType1(null); + var model = new ContentModel(content); + var view = new ContentType1TestPage(); + var viewData = GetViewDataDictionary>(model); + + await view.SetViewDataAsyncX(viewData); + + Assert.IsInstanceOf(view.Model); + } + + [Test] + public async Task RenderModelOf_ContentType2_To_ContentType1() + { + var content = new ContentType2(null); + var model = new ContentModel(content); + var view = new ContentType1TestPage(); + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) + { + Model = model + }; + + await view.SetViewDataAsyncX(viewData); + + Assert.IsInstanceOf(view.Model); + } + + [Test] + public async Task RenderModelOf_ContentType1_To_ContentType2() + { + + var content = new ContentType1(null); + var model = new ContentModel(content); + var view = new ContentType2TestPage(); + var viewData = GetViewDataDictionary(model); + + Assert.ThrowsAsync(async () => await view.SetViewDataAsyncX(viewData)); + } + + [Test] + public void RenderModelOf_ContentType1_To_RenderModelOf_ContentType1() + { + var content = new ContentType1(null); + var model = new ContentModel(content); + var view = new RenderModelOfContentType1TestPage(); + var viewData = GetViewDataDictionary>(model); + + view.ViewData = viewData; + + Assert.IsInstanceOf>(view.Model); + Assert.IsInstanceOf(view.Model.Content); + } + + [Test] + public async Task RenderModelOf_ContentType2_To_RenderModelOf_ContentType1() + { + var content = new ContentType2(null); + var model = new ContentModel(content); + var view = new RenderModelOfContentType1TestPage(); + var viewData = GetViewDataDictionary>(model); + + await view.SetViewDataAsyncX(viewData); + + Assert.IsInstanceOf>(view.Model); + Assert.IsInstanceOf(view.Model.Content); + } + + [Test] + public void RenderModelOf_ContentType1_To_RenderModelOf_ContentType2() + { + var content = new ContentType1(null); + var model = new ContentModel(content); + var view = new RenderModelOfContentType2TestPage(); + var viewData = GetViewDataDictionary(model); + + Assert.ThrowsAsync(async () => await view.SetViewDataAsyncX(viewData)); + } + + #endregion + + #region ContentType To ... + + [Test] + public async Task ContentType1_To_RenderModel() + { + var content = new ContentType1(null); + var view = new RenderModelTestPage(); + + var viewData = GetViewDataDictionary(content); + + await view.SetViewDataAsyncX(viewData); + + Assert.IsInstanceOf(view.Model); + } + + [Test] + public async Task ContentType1_To_RenderModelOf_ContentType1() + { + var content = new ContentType1(null); + var view = new RenderModelOfContentType1TestPage(); + + var viewData = GetViewDataDictionary(content); + await view.SetViewDataAsyncX(viewData); + + Assert.IsInstanceOf>(view.Model); + Assert.IsInstanceOf(view.Model.Content); + } + + [Test] + public async Task ContentType2_To_RenderModelOf_ContentType1() + { + // Same as above but with ContentModel + var content = new ContentType2(null); + var view = new RenderModelOfContentType1TestPage(); + var viewData = GetViewDataDictionary(content); + + await view.SetViewDataAsyncX(viewData); + + Assert.IsInstanceOf>(view.Model); + Assert.IsInstanceOf(view.Model.Content); + } + + [Test] + public void ContentType1_To_RenderModelOf_ContentType2() + { + var content = new ContentType1(null); + var view = new RenderModelOfContentType2TestPage(); + var viewData = GetViewDataDictionary(content); + + Assert.ThrowsAsync(async () => await view.SetViewDataAsyncX(viewData)); + } + + [Test] + public async Task ContentType1_To_ContentType1() + { + var content = new ContentType1(null); + var view = new ContentType1TestPage(); + var viewData = GetViewDataDictionary(content); + + await view.SetViewDataAsyncX(viewData); + + Assert.IsInstanceOf(view.Model); + } + + [Test] + public void ContentType1_To_ContentType2() + { + var content = new ContentType1(null); + var view = new ContentType2TestPage(); + var viewData = GetViewDataDictionary(content); + + Assert.ThrowsAsync(async () => await view.SetViewDataAsyncX(viewData)); + } + + [Test] + public async Task ContentType2_To_ContentType1() + { + var content = new ContentType2(null); + var view = new ContentType1TestPage(); + var viewData = GetViewDataDictionary(content); + + await view.SetViewDataAsyncX(viewData); + + Assert.IsInstanceOf(view.Model); + } + + #endregion + + #region Test helpers methods + + private ViewDataDictionary GetViewDataDictionary(object model) + { + var sourceViewDataDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); + return new ViewDataDictionary(sourceViewDataDictionary, model); + } + + private ViewDataDictionary GetViewDataDictionary(object model) + { + var sourceViewDataDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); + return new ViewDataDictionary(sourceViewDataDictionary) + { + Model = model + }; + } + + #endregion + + #region Test elements + + public class ContentType1 : PublishedContentWrapped + { + public ContentType1(IPublishedContent content) : base(content) {} + } + + public class ContentType2 : ContentType1 + { + public ContentType2(IPublishedContent content) : base(content) { } + } + + public class TestPage : UmbracoViewPage + { + public override Task ExecuteAsync() + { + throw new NotImplementedException(); + } + + public async Task SetViewDataAsyncX(ViewDataDictionary viewData) + { + await SetViewDataAsync(viewData); + } + } + + public class RenderModelTestPage : TestPage + { } + + public class ContentType1TestPage : TestPage + { } + + public class ContentType2TestPage : TestPage + { } + + public class RenderModelOfContentType1TestPage : TestPage> + { } + + public class RenderModelOfContentType2TestPage : TestPage> + { } + + #endregion + } +} diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/AspNetCoreHostingEnvironmentTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/AspNetCoreHostingEnvironmentTests.cs index 1d6e619640..1e579cc7dd 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/AspNetCoreHostingEnvironmentTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/AspNetCoreHostingEnvironmentTests.cs @@ -9,7 +9,7 @@ using Umbraco.Tests.TestHelpers; using Umbraco.Tests.UnitTests.AutoFixture; using Umbraco.Web.Common.AspNetCore; -namespace Umbraco.Tests.IO +namespace Umbraco.Tests.UnitTests.Umbraco.Web.Website { [TestFixture] public class AspNetCoreHostingEnvironmentTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Controllers/SurfaceControllerTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Controllers/SurfaceControllerTests.cs index ee2d5f3eab..dbeb8f6e7c 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Controllers/SurfaceControllerTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Controllers/SurfaceControllerTests.cs @@ -19,8 +19,9 @@ using Umbraco.Web.Routing; using Umbraco.Web.Security; using Umbraco.Web.Website; using Umbraco.Web.Website.Controllers; +using CoreConstants = Umbraco.Core.Constants; -namespace Umbraco.Tests.Integration +namespace Umbraco.Tests.UnitTests.Umbraco.Web.Website.Controllers { [TestFixture] [UmbracoTest(WithApplication = true)] @@ -183,7 +184,7 @@ namespace Umbraco.Tests.Integration }; var routeData = new RouteData(); - routeData.DataTokens.Add(Core.Constants.Web.UmbracoRouteDefinitionDataToken, routeDefinition); + routeData.DataTokens.Add(CoreConstants.Web.UmbracoRouteDefinitionDataToken, routeDefinition); var ctrl = new TestSurfaceController(umbracoContextAccessor, Mock.Of(), Mock.Of()); ctrl.ControllerContext = new ControllerContext() diff --git a/src/Umbraco.Tests/Cache/HttpRequestAppCacheTests.cs b/src/Umbraco.Tests/Cache/HttpRequestAppCacheTests.cs deleted file mode 100644 index 2eea382bd3..0000000000 --- a/src/Umbraco.Tests/Cache/HttpRequestAppCacheTests.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Moq; -using NUnit.Framework; -using Umbraco.Core.Cache; -using Umbraco.Core.Composing; -using Umbraco.Core.Logging; -using Umbraco.Tests.TestHelpers; - -namespace Umbraco.Tests.Cache -{ - [TestFixture] - public class HttpRequestAppCacheTests : AppCacheTests - { - private HttpRequestAppCache _appCache; - private FakeHttpContextFactory _ctx; - - public override void Setup() - { - base.Setup(); - _ctx = new FakeHttpContextFactory("http://localhost/test"); - _appCache = new HttpRequestAppCache(() => _ctx.HttpContext.Items); - } - - internal override IAppCache AppCache - { - get { return _appCache; } - } - - protected override int GetTotalItemCount - { - get { return _ctx.HttpContext.Items.Count; } - } - } - - [TestFixture] - public class DictionaryAppCacheTests : AppCacheTests - { - private DictionaryAppCache _appCache; - - public override void Setup() - { - base.Setup(); - _appCache = new DictionaryAppCache(); - } - - internal override IAppCache AppCache - { - get { return _appCache; } - } - - protected override int GetTotalItemCount - { - get { return _appCache.Count; } - } - } -} diff --git a/src/Umbraco.Tests/Persistence/Mappers/MapperTestBase.cs b/src/Umbraco.Tests/Persistence/Mappers/MapperTestBase.cs index 797fdb3222..8c2cdf4551 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/MapperTestBase.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/MapperTestBase.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using Moq; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Infrastructure.Persistence.Mappers; using Umbraco.Persistance.SqlCe; namespace Umbraco.Tests.Persistence.Mappers @@ -17,7 +18,7 @@ namespace Umbraco.Tests.Persistence.Mappers return new Lazy(() => sqlContext); } - protected ConcurrentDictionary> CreateMaps() - => new ConcurrentDictionary>(); + protected MapperConfigurationStore CreateMaps() + => new MapperConfigurationStore(); } } diff --git a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs deleted file mode 100644 index 0cd26442be..0000000000 --- a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs +++ /dev/null @@ -1,543 +0,0 @@ -using System; -using System.Linq; -using Microsoft.Extensions.Logging; -using Moq; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.Models; -using Umbraco.Core.Models.Membership; -using Umbraco.Core.Persistence.Repositories; -using Umbraco.Core.Persistence.Repositories.Implement; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Scoping; -using Umbraco.Core.Serialization; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; -using Umbraco.Tests.Testing; -using Umbraco.Core.Configuration; -using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Persistence.Mappers; -using Umbraco.Tests.Common.Builders; -using Umbraco.Tests.Common.Builders.Extensions; -using MockedUser = Umbraco.Tests.TestHelpers.Entities.MockedUser; - -namespace Umbraco.Tests.Persistence.Repositories -{ - // TODO: Move the remaining parts to Integration tests - - [TestFixture] - [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, WithApplication = true, Logger = UmbracoTestOptions.Logger.Console)] - public class UserRepositoryTest : TestWithDatabaseBase - { - private MediaRepository CreateMediaRepository(IScopeProvider provider, out IMediaTypeRepository mediaTypeRepository) - { - var accessor = (IScopeAccessor) provider; - var globalSettings = new GlobalSettings(); - var templateRepository = new TemplateRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), TestObjects.GetFileSystemsMock(), IOHelper, ShortStringHelper); - var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches, ShortStringHelper); - var languageRepository = new LanguageRepository(accessor, AppCaches, LoggerFactory.CreateLogger(), Microsoft.Extensions.Options.Options.Create(globalSettings)); - mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches, Mock.Of>(), commonRepository, languageRepository, ShortStringHelper); - var tagRepository = new TagRepository(accessor, AppCaches, Mock.Of>()); - var relationTypeRepository = new RelationTypeRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger()); - var entityRepository = new EntityRepository(accessor); - var relationRepository = new RelationRepository(accessor, LoggerFactory.CreateLogger(), relationTypeRepository, entityRepository); - var propertyEditors = new Lazy(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty()))); - var mediaUrlGenerators = new MediaUrlGeneratorCollection(Enumerable.Empty()); - var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty()); - var repository = new MediaRepository(accessor, AppCaches, Mock.Of>(), LoggerFactory, mediaTypeRepository, tagRepository, Mock.Of(), relationRepository, relationTypeRepository, propertyEditors, mediaUrlGenerators, dataValueReferences, DataTypeService); - return repository; - } - - private DocumentRepository CreateContentRepository(IScopeProvider provider, out IContentTypeRepository contentTypeRepository) - { - ITemplateRepository tr; - return CreateContentRepository(provider, out contentTypeRepository, out tr); - } - - private DocumentRepository CreateContentRepository(IScopeProvider provider, out IContentTypeRepository contentTypeRepository, out ITemplateRepository templateRepository) - { - var accessor = (IScopeAccessor) provider; - var globalSettings = new GlobalSettings(); - templateRepository = new TemplateRepository(accessor, AppCaches, LoggerFactory.CreateLogger(), TestObjects.GetFileSystemsMock(), IOHelper, ShortStringHelper); - var tagRepository = new TagRepository(accessor, AppCaches, LoggerFactory.CreateLogger()); - var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches, ShortStringHelper); - var languageRepository = new LanguageRepository(accessor, AppCaches, LoggerFactory.CreateLogger(), Microsoft.Extensions.Options.Options.Create(globalSettings)); - contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, LoggerFactory.CreateLogger(), commonRepository, languageRepository, ShortStringHelper); - var relationTypeRepository = new RelationTypeRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger()); - var entityRepository = new EntityRepository(accessor); - var relationRepository = new RelationRepository(accessor, LoggerFactory.CreateLogger(), relationTypeRepository, entityRepository); - var propertyEditors = new Lazy(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty()))); - var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty()); - var repository = new DocumentRepository(accessor, AppCaches, LoggerFactory.CreateLogger(), LoggerFactory, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences, DataTypeService); - return repository; - } - - private UserRepository CreateRepository(IScopeProvider provider) - { - var accessor = (IScopeAccessor) provider; - var globalSettings = new GlobalSettings(); - var repository = new UserRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), Mappers, Microsoft.Extensions.Options.Options.Create(globalSettings), Microsoft.Extensions.Options.Options.Create(new UserPasswordConfigurationSettings()), new JsonNetSerializer()); - return repository; - } - - private UserGroupRepository CreateUserGroupRepository(IScopeProvider provider) - { - var accessor = (IScopeAccessor) provider; - return new UserGroupRepository(accessor, AppCaches.Disabled, LoggerFactory.CreateLogger(), LoggerFactory, ShortStringHelper); - } - - [Test] - public void Validate_Login_Session() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - var user = MockedUser.CreateUser(); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - repository.Save(user); - } - - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - var sessionId = repository.CreateLoginSession(user.Id, "1.2.3.4"); - - // manually update this record to be in the past - scope.Database.Execute(SqlContext.Sql() - .Update(u => u.Set(x => x.LoggedOutUtc, DateTime.UtcNow.AddDays(-100))) - .Where(x => x.SessionId == sessionId)); - - var isValid = repository.ValidateLoginSession(user.Id, sessionId); - Assert.IsFalse(isValid); - - // create a new one - sessionId = repository.CreateLoginSession(user.Id, "1.2.3.4"); - isValid = repository.ValidateLoginSession(user.Id, sessionId); - Assert.IsTrue(isValid); - } - } - - [Test] - public void Can_Perform_Add_On_UserRepository() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - - var user = MockedUser.CreateUser(); - - // Act - repository.Save(user); - - - // Assert - Assert.That(user.HasIdentity, Is.True); - } - } - - [Test] - public void Can_Perform_Multiple_Adds_On_UserRepository() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - - var user1 = MockedUser.CreateUser("1"); - var use2 = MockedUser.CreateUser("2"); - - // Act - repository.Save(user1); - - repository.Save(use2); - - - // Assert - Assert.That(user1.HasIdentity, Is.True); - Assert.That(use2.HasIdentity, Is.True); - } - } - - [Test] - public void Can_Verify_Fresh_Entity_Is_Not_Dirty() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - - var user = MockedUser.CreateUser(); - repository.Save(user); - - - // Act - var resolved = repository.Get((int)user.Id); - bool dirty = ((User)resolved).IsDirty(); - - // Assert - Assert.That(dirty, Is.False); - } - } - - [Test] - public void Can_Perform_Update_On_UserRepository() - { - var ct = MockedContentTypes.CreateBasicContentType("test"); - var mt = MockedContentTypes.CreateSimpleMediaType("testmedia", "TestMedia"); - - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var userRepository = CreateRepository(provider); - var contentRepository = CreateContentRepository(provider, out var contentTypeRepo); - var mediaRepository = CreateMediaRepository(provider, out var mediaTypeRepo); - var userGroupRepository = CreateUserGroupRepository(provider); - - contentTypeRepo.Save(ct); - mediaTypeRepo.Save(mt); - - var content = MockedContent.CreateBasicContent(ct); - var media = MockedMedia.CreateSimpleMedia(mt, "asdf", -1); - - contentRepository.Save(content); - mediaRepository.Save(media); - - var user = CreateAndCommitUserWithGroup(userRepository, userGroupRepository); - - // Act - var resolved = (User) userRepository.Get(user.Id); - - resolved.Name = "New Name"; - //the db column is not used, default permissions are taken from the user type's permissions, this is a getter only - //resolved.DefaultPermissions = "ZYX"; - resolved.Language = "fr"; - resolved.IsApproved = false; - resolved.RawPasswordValue = "new"; - resolved.IsLockedOut = true; - resolved.StartContentIds = new[] { content.Id }; - resolved.StartMediaIds = new[] { media.Id }; - resolved.Email = "new@new.com"; - resolved.Username = "newName"; - - userRepository.Save(resolved); - - var updatedItem = (User) userRepository.Get(user.Id); - - // Assert - Assert.That(updatedItem.Id, Is.EqualTo(resolved.Id)); - Assert.That(updatedItem.Name, Is.EqualTo(resolved.Name)); - Assert.That(updatedItem.Language, Is.EqualTo(resolved.Language)); - Assert.That(updatedItem.IsApproved, Is.EqualTo(resolved.IsApproved)); - Assert.That(updatedItem.RawPasswordValue, Is.EqualTo(resolved.RawPasswordValue)); - Assert.That(updatedItem.IsLockedOut, Is.EqualTo(resolved.IsLockedOut)); - Assert.IsTrue(updatedItem.StartContentIds.UnsortedSequenceEqual(resolved.StartContentIds)); - Assert.IsTrue(updatedItem.StartMediaIds.UnsortedSequenceEqual(resolved.StartMediaIds)); - Assert.That(updatedItem.Email, Is.EqualTo(resolved.Email)); - Assert.That(updatedItem.Username, Is.EqualTo(resolved.Username)); - Assert.That(updatedItem.AllowedSections.Count(), Is.EqualTo(resolved.AllowedSections.Count())); - foreach (var allowedSection in resolved.AllowedSections) - Assert.IsTrue(updatedItem.AllowedSections.Contains(allowedSection)); - } - } - - [Test] - public void Can_Perform_Delete_On_UserRepository() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - - var user = MockedUser.CreateUser(); - - // Act - repository.Save(user); - - var id = user.Id; - - var repository2 = new UserRepository((IScopeAccessor) provider, AppCaches.Disabled, LoggerFactory.CreateLogger(), - Mock.Of(), - Microsoft.Extensions.Options.Options.Create(new GlobalSettings()), - Microsoft.Extensions.Options.Options.Create(new UserPasswordConfigurationSettings()), - Mock.Of()); - - repository2.Delete(user); - - - var resolved = repository2.Get((int) id); - - // Assert - Assert.That(resolved, Is.Null); - } - } - - [Test] - public void Can_Perform_Get_On_UserRepository() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - var userGroupRepository = CreateUserGroupRepository(provider); - - var user = CreateAndCommitUserWithGroup(repository, userGroupRepository); - - // Act - var updatedItem = repository.Get(user.Id); - - // FIXME: this test cannot work, user has 2 sections but the way it's created, - // they don't show, so the comparison with updatedItem fails - fix! - - // Assert - AssertPropertyValues(updatedItem, user); - } - } - - [Test] - public void Can_Perform_GetByQuery_On_UserRepository() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - - CreateAndCommitMultipleUsers(repository); - - // Act - var query = scope.SqlContext.Query().Where(x => x.Username == "TestUser1"); - var result = repository.Get(query); - - // Assert - Assert.That(result.Count(), Is.GreaterThanOrEqualTo(1)); - } - } - - [Test] - public void Can_Perform_GetAll_By_Param_Ids_On_UserRepository() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - - var users = CreateAndCommitMultipleUsers(repository); - - // Act - var result = repository.GetMany((int) users[0].Id, (int) users[1].Id); - - // Assert - Assert.That(result, Is.Not.Null); - Assert.That(result.Any(), Is.True); - Assert.That(result.Count(), Is.EqualTo(2)); - } - } - - [Test] - public void Can_Perform_GetAll_On_UserRepository() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - - CreateAndCommitMultipleUsers(repository); - - // Act - var result = repository.GetMany(); - - // Assert - Assert.That(result, Is.Not.Null); - Assert.That(result.Any(), Is.True); - Assert.That(result.Count(), Is.GreaterThanOrEqualTo(3)); - } - } - - [Test] - public void Can_Perform_Exists_On_UserRepository() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - - var users = CreateAndCommitMultipleUsers(repository); - - // Act - var exists = repository.Exists(users[0].Id); - - // Assert - Assert.That(exists, Is.True); - } - } - - [Test] - public void Can_Perform_Count_On_UserRepository() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - - var users = CreateAndCommitMultipleUsers(repository); - - // Act - var query = scope.SqlContext.Query().Where(x => x.Username == "TestUser1" || x.Username == "TestUser2"); - var result = repository.Count(query); - - // Assert - Assert.AreEqual(2, result); - } - } - - [Test] - public void Can_Get_Paged_Results_By_Query_And_Filter_And_Groups() - { - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - - var users = CreateAndCommitMultipleUsers(repository); - var query = provider.SqlContext.Query().Where(x => x.Username == "TestUser1" || x.Username == "TestUser2"); - - try - { - scope.Database.AsUmbracoDatabase().EnableSqlTrace = true; - scope.Database.AsUmbracoDatabase().EnableSqlCount = true; - - // Act - var result = repository.GetPagedResultsByQuery(query, 0, 10, out var totalRecs, user => user.Id, Direction.Ascending, - excludeUserGroups: new[] { Constants.Security.TranslatorGroupAlias }, - filter: provider.SqlContext.Query().Where(x => x.Id > -1)); - - // Assert - Assert.AreEqual(2, totalRecs); - } - finally - { - scope.Database.AsUmbracoDatabase().EnableSqlTrace = false; - scope.Database.AsUmbracoDatabase().EnableSqlCount = false; - } - } - - } - - [Test] - public void Can_Get_Paged_Results_With_Filter_And_Groups() - { - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - - var users = CreateAndCommitMultipleUsers(repository); - - try - { - scope.Database.AsUmbracoDatabase().EnableSqlTrace = true; - scope.Database.AsUmbracoDatabase().EnableSqlCount = true; - - // Act - var result = repository.GetPagedResultsByQuery(null, 0, 10, out var totalRecs, user => user.Id, Direction.Ascending, - includeUserGroups: new[] { Constants.Security.AdminGroupAlias, Constants.Security.SensitiveDataGroupAlias }, - excludeUserGroups: new[] { Constants.Security.TranslatorGroupAlias }, - filter: provider.SqlContext.Query().Where(x => x.Id == -1)); - - // Assert - Assert.AreEqual(1, totalRecs); - } - finally - { - scope.Database.AsUmbracoDatabase().EnableSqlTrace = false; - scope.Database.AsUmbracoDatabase().EnableSqlCount = false; - } - } - } - - [Test] - public void Can_Invalidate_SecurityStamp_On_Username_Change() - { - // Arrange - var provider = TestObjects.GetScopeProvider(LoggerFactory); - using (var scope = provider.CreateScope(autoComplete: true)) - { - var repository = CreateRepository(provider); - var userGroupRepository = CreateUserGroupRepository(provider); - - var user = CreateAndCommitUserWithGroup(repository, userGroupRepository); - var originalSecurityStamp = user.SecurityStamp; - - // Ensure when user generated a security stamp is present - Assert.That(user.SecurityStamp, Is.Not.Null); - Assert.That(user.SecurityStamp, Is.Not.Empty); - - // Update username - user.Username = user.Username + "UPDATED"; - repository.Save(user); - - // Get the user - var updatedUser = repository.Get(user.Id); - - // Ensure the Security Stamp is invalidated & no longer the same - Assert.AreNotEqual(originalSecurityStamp, updatedUser.SecurityStamp); - } - } - - private void AssertPropertyValues(IUser updatedItem, IUser originalUser) - { - Assert.That(updatedItem.Id, Is.EqualTo(originalUser.Id)); - Assert.That(updatedItem.Name, Is.EqualTo(originalUser.Name)); - Assert.That(updatedItem.Language, Is.EqualTo(originalUser.Language)); - Assert.That(updatedItem.IsApproved, Is.EqualTo(originalUser.IsApproved)); - Assert.That(updatedItem.RawPasswordValue, Is.EqualTo(originalUser.RawPasswordValue)); - Assert.That(updatedItem.IsLockedOut, Is.EqualTo(originalUser.IsLockedOut)); - Assert.IsTrue(updatedItem.StartContentIds.UnsortedSequenceEqual(originalUser.StartContentIds)); - Assert.IsTrue(updatedItem.StartMediaIds.UnsortedSequenceEqual(originalUser.StartMediaIds)); - Assert.That(updatedItem.Email, Is.EqualTo(originalUser.Email)); - Assert.That(updatedItem.Username, Is.EqualTo(originalUser.Username)); - Assert.That(updatedItem.AllowedSections.Count(), Is.EqualTo(originalUser.AllowedSections.Count())); - foreach (var allowedSection in originalUser.AllowedSections) - Assert.IsTrue(updatedItem.AllowedSections.Contains(allowedSection)); - } - - private static User CreateAndCommitUserWithGroup(IUserRepository repository, IUserGroupRepository userGroupRepository) - { - var user = MockedUser.CreateUser(); - repository.Save(user); - - - var group = MockedUserGroup.CreateUserGroup(); - userGroupRepository.AddOrUpdateGroupWithUsers(@group, new[] { user.Id }); - - user.AddGroup(group); - - return user; - } - private IUser[] CreateAndCommitMultipleUsers(IUserRepository repository) - { - var user1 = new UserBuilder().WithoutIdentity().WithSuffix("1").Build(); - var user2 = new UserBuilder().WithoutIdentity().WithSuffix("2").Build(); - var user3 = new UserBuilder().WithoutIdentity().WithSuffix("3").Build(); - repository.Save(user1); - repository.Save(user2); - repository.Save(user3); - return new IUser[] { user1, user2, user3 }; - } - - } -} diff --git a/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs b/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs index 00ab29bfea..342aa99b47 100644 --- a/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs +++ b/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs @@ -6,6 +6,7 @@ using Umbraco.Core.Models; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; using System.Linq; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Core.Services; using Umbraco.Tests.Testing; @@ -15,13 +16,6 @@ namespace Umbraco.Tests.Publishing [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] public class PublishingStrategyTests : TestWithDatabaseBase { - public override void SetUp() - { - base.SetUp(); - - //LegacyUmbracoSettings.SettingsFilePath = Current.IOHelper.MapPath(SystemDirectories.Config + Path.DirectorySeparatorChar, false); - } - private IContent _homePage; [NUnit.Framework.Ignore("fixme - ignored test")] diff --git a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs deleted file mode 100644 index e5594a0778..0000000000 --- a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs +++ /dev/null @@ -1,348 +0,0 @@ -using System; -using System.Configuration; -using System.Data.SqlServerCe; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Web; -using Examine; -using Microsoft.Extensions.Logging; -using Moq; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Composing; -using Umbraco.Core.Configuration; -using Umbraco.Core.Hosting; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using Umbraco.Core.Migrations.Install; -using Umbraco.Core.Models; -using Umbraco.Core.Models.PublishedContent; -using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.Mappers; -using Umbraco.Core.Runtime; -using Umbraco.Core.Scoping; -using Umbraco.Core.Services; -using Umbraco.Core.Sync; -using Umbraco.Tests.TestHelpers; -using Umbraco.Web; -using Umbraco.Web.Cache; -using Umbraco.Web.Macros; -using Umbraco.Web.PublishedCache; -using Umbraco.Web.Routing; -using Umbraco.Web.Runtime; -using File = System.IO.File; -using Current = Umbraco.Web.Composing.Current; -using Umbraco.Tests.Common; -using Umbraco.Tests.Common.Composing; -using Umbraco.Core.Media; -using Umbraco.Tests.Common.Builders; -using Microsoft.Extensions.Options; -using Umbraco.Core.Configuration.Models; - -namespace Umbraco.Tests.Runtimes -{ - [TestFixture] - public class StandaloneTests - { - [Test] - [Explicit("This test must be run manually")] - public void StandaloneTest() - { - IFactory factory = null; - - // clear - foreach (var file in Directory.GetFiles(Path.Combine(TestHelper.IOHelper.MapPath("~/App_Data")), "NuCache.*")) - File.Delete(file); - - // settings - // reset the current version to 0.0.0, clear connection strings - ConfigurationManager.AppSettings[Constants.AppSettings.ConfigurationStatus] = ""; - // FIXME: we need a better management of settings here (and, true config files?) - - var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); - // create the very basic and essential things we need - var profiler = new LogProfiler(loggerFactory.CreateLogger()); - var profilingLogger = new ProfilingLogger(loggerFactory.CreateLogger("ProfilingLogger"), profiler); - var appCaches = AppCaches.Disabled; - var globalSettings = new GlobalSettings(); - var connectionStrings = new ConnectionStrings(); - var typeFinder = TestHelper.GetTypeFinder(); - var databaseFactory = new UmbracoDatabaseFactory(loggerFactory.CreateLogger(), loggerFactory, Options.Create(globalSettings), Options.Create(connectionStrings), new Lazy(() => factory.GetInstance()), TestHelper.DbProviderFactoryCreator); - var ioHelper = TestHelper.IOHelper; - var hostingEnvironment = Mock.Of(); - var typeLoader = new TypeLoader(typeFinder, appCaches.RuntimeCache, new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), loggerFactory.CreateLogger(), profilingLogger); - var mainDom = new SimpleMainDom(); - var umbracoVersion = TestHelper.GetUmbracoVersion(); - var backOfficeInfo = TestHelper.GetBackOfficeInfo(); - var runtimeState = new RuntimeState(globalSettings, umbracoVersion, databaseFactory, loggerFactory.CreateLogger()); - var variationContextAccessor = TestHelper.VariationContextAccessor; - - // create the register and the composition - var register = TestHelper.GetRegister(); - var composition = new Composition(register, typeLoader, profilingLogger, runtimeState, ioHelper, appCaches); - composition.RegisterEssentials(loggerFactory.CreateLogger("Essentials"), loggerFactory, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator, hostingEnvironment, backOfficeInfo); - - // create the core runtime and have it compose itself - var coreRuntime = new CoreRuntime(globalSettings, connectionStrings, umbracoVersion, ioHelper, loggerFactory, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder, AppCaches.NoCache); - - // determine actual runtime level - runtimeState.DetermineRuntimeLevel(); - Console.WriteLine(runtimeState.Level); - // going to be Install BUT we want to force components to be there (nucache etc) - runtimeState.Level = RuntimeLevel.Run; - - var composerTypes = typeLoader.GetTypes() // all of them - .Where(x => !x.FullName.StartsWith("Umbraco.Tests.")) // exclude test components - .Where(x => x != typeof(WebInitialComposer) && x != typeof(WebFinalComposer)); // exclude web runtime - var composers = new Composers(composition, composerTypes, Enumerable.Empty(), loggerFactory.CreateLogger(), profilingLogger); - composers.Compose(); - - // must registers stuff that WebRuntimeComponent would register otherwise - // FIXME: UmbracoContext creates a snapshot that it does not register with the accessor - // and so, we have to use the UmbracoContextPublishedSnapshotAccessor - // the UmbracoContext does not know about the accessor - // else that would be a catch-22 where they both know about each other? - //composition.Register(Lifetime.Singleton); - composition.Register(Lifetime.Singleton); - composition.Register(Lifetime.Singleton); - composition.Register(Lifetime.Singleton); - composition.Register(Lifetime.Singleton); - composition.Register(_ => Mock.Of(), Lifetime.Singleton); - composition.RegisterUnique(f => new DistributedCache(f.GetInstance(), f.GetInstance())); - composition.Register(_ => Mock.Of(), Lifetime.Singleton); - composition.WithCollectionBuilder().Append(); - composition.RegisterUnique(); - composition.RegisterUnique(); - composition.RegisterUnique(); - composition.RegisterUnique(); - composition.RegisterUnique(_ => new MediaUrlProviderCollection(Enumerable.Empty())); - - // TODO: found these registration were necessary here as dependencies for ComponentCollection - // are not resolved. Need to check this if these explicit registrations are the best way to handle this. - var contentSettings = new ContentSettings(); - var coreDebugSettings = new CoreDebugSettings(); - var nuCacheSettings = new NuCacheSettings(); - var requestHandlerSettings = new RequestHandlerSettings(); - var userPasswordConfigurationSettings = new UserPasswordConfigurationSettings(); - var webRoutingSettings = new WebRoutingSettings(); - - composition.Register(x => Options.Create(globalSettings)); - composition.Register(x => Options.Create(contentSettings)); - composition.Register(x => Options.Create(coreDebugSettings)); - composition.Register(x => Options.Create(nuCacheSettings)); - composition.Register(x => Options.Create(requestHandlerSettings)); - composition.Register(x => Options.Create(userPasswordConfigurationSettings)); - composition.Register(x => Options.Create(webRoutingSettings)); - - // initialize some components only/individually - composition.WithCollectionBuilder() - .Clear() - .Append(); - - // configure - - // create and register the factory - Current.Factory = factory = composition.CreateFactory(); - - // instantiate and initialize components - var components = factory.GetInstance(); - - // do stuff - Console.WriteLine(runtimeState.Level); - - // install - if (true || runtimeState.Level == RuntimeLevel.Install) - { - var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - var file = databaseFactory.Configured ? Path.Combine(path, "UmbracoNPocoTests.sdf") : Path.Combine(path, "Umbraco.sdf"); - if (File.Exists(file)) - File.Delete(file); - - // create the database file - // databaseBuilder.ConfigureEmbeddedDatabaseConnection() can do it too, - // but then it wants to write the connection string to web.config = bad - var connectionString = databaseFactory.Configured ? databaseFactory.ConnectionString : "Data Source=|DataDirectory|\\Umbraco.sdf;Flush Interval=1;"; - using (var engine = new SqlCeEngine(connectionString)) - { - engine.CreateDatabase(); - } - - //var databaseBuilder = factory.GetInstance(); - //databaseFactory.Configure(DatabaseBuilder.EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe); - //databaseBuilder.CreateDatabaseSchemaAndData(); - - if (!databaseFactory.Configured) - databaseFactory.Configure(DatabaseBuilder.EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe); - - var scopeProvider = factory.GetInstance(); - using (var scope = scopeProvider.CreateScope()) - { - var creator = new DatabaseSchemaCreator(scope.Database, loggerFactory.CreateLogger(), loggerFactory, umbracoVersion); - creator.InitializeDatabaseSchema(); - scope.Complete(); - } - } - - // done installing - runtimeState.Level = RuntimeLevel.Run; - - components.Initialize(); - - // instantiate to register events - // should be done by Initialize? - // should we invoke Initialize? - _ = factory.GetInstance(); - - // at that point, Umbraco can run! - // though, we probably still need to figure out what depends on HttpContext... - var contentService = factory.GetInstance(); - var content = contentService.GetById(1234); - Assert.IsNull(content); - - // create a document type and a document - var contentType = new ContentType(TestHelper.ShortStringHelper, -1) { Alias = "ctype", Name = "ctype" }; - factory.GetInstance().Save(contentType); - content = new Content("test", -1, contentType); - contentService.Save(content); - - // assert that it is possible to get the document back - content = contentService.GetById(content.Id); - Assert.IsNotNull(content); - Assert.AreEqual("test", content.Name); - - // need an UmbracoCOntext to access the cache - var umbracoContextFactory = factory.GetInstance(); - var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); - var umbracoContext = umbracoContextReference.UmbracoContext; - - // assert that there is no published document - var pcontent = umbracoContext.Content.GetById(content.Id); - Assert.IsNull(pcontent); - - // but a draft document - pcontent = umbracoContext.Content.GetById(true, content.Id); - Assert.IsNotNull(pcontent); - Assert.AreEqual("test", pcontent.Name(variationContextAccessor)); - Assert.IsTrue(pcontent.IsDraft()); - - // no published url - Assert.AreEqual("#", pcontent.Url()); - - // now publish the document + make some unpublished changes - contentService.SaveAndPublish(content); - content.Name = "testx"; - contentService.Save(content); - - // assert that snapshot has been updated and there is now a published document - pcontent = umbracoContext.Content.GetById(content.Id); - Assert.IsNotNull(pcontent); - Assert.AreEqual("test", pcontent.Name(variationContextAccessor)); - Assert.IsFalse(pcontent.IsDraft()); - - // but the url is the published one - no draft url - Assert.AreEqual("/test/", pcontent.Url()); - - // and also an updated draft document - pcontent = umbracoContext.Content.GetById(true, content.Id); - Assert.IsNotNull(pcontent); - Assert.AreEqual("testx", pcontent.Name(variationContextAccessor)); - Assert.IsTrue(pcontent.IsDraft()); - - // and the published document has a url - Assert.AreEqual("/test/", pcontent.Url()); - - umbracoContextReference.Dispose(); - mainDom.Stop(); - components.Terminate(); - - // exit! - } - - [Test] - [Explicit("This test must be run manually")] - public void ValidateComposition() - { - // this is almost what CoreRuntime does, without - // - managing MainDom - // - configuring for unhandled exceptions, assembly resolution, application root path - // - testing for database, and for upgrades (runtime level) - // - assigning the factory to Current.Factory - - // create the very basic and essential things we need - var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); - var profiler = Mock.Of(); - var profilingLogger = new ProfilingLogger(loggerFactory.CreateLogger("ProfilingLogger"), profiler); - var appCaches = AppCaches.Disabled; - var databaseFactory = Mock.Of(); - var typeFinder = TestHelper.GetTypeFinder(); - var ioHelper = TestHelper.IOHelper; - var typeLoader = new TypeLoader(typeFinder, appCaches.RuntimeCache, new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), loggerFactory.CreateLogger(), profilingLogger); - var runtimeState = Mock.Of(); - var hostingEnvironment = Mock.Of(); - var backOfficeInfo = TestHelper.GetBackOfficeInfo(); - Mock.Get(runtimeState).Setup(x => x.Level).Returns(RuntimeLevel.Run); - var mainDom = Mock.Of(); - Mock.Get(mainDom).Setup(x => x.IsMainDom).Returns(true); - - // create the register and the composition - var register = TestHelper.GetRegister(); - var composition = new Composition(register, typeLoader, profilingLogger, runtimeState, ioHelper, appCaches); - var umbracoVersion = TestHelper.GetUmbracoVersion(); - composition.RegisterEssentials(loggerFactory.CreateLogger("RegisterEssentials"), loggerFactory, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator, hostingEnvironment, backOfficeInfo); - - // create the core runtime and have it compose itself - var globalSettings = new GlobalSettings(); - var connectionStrings = new ConnectionStrings(); - - var coreRuntime = new CoreRuntime(globalSettings, connectionStrings, umbracoVersion, ioHelper, loggerFactory, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder, AppCaches.NoCache); - - // get the components - // all of them? - var composerTypes = typeLoader.GetTypes(); - // filtered - composerTypes = composerTypes - .Where(x => !x.FullName.StartsWith("Umbraco.Tests")); - // single? - //var componentTypes = new[] { typeof(CoreRuntimeComponent) }; - var composers = new Composers(composition, composerTypes, Enumerable.Empty(), loggerFactory.CreateLogger(), profilingLogger); - - // get components to compose themselves - composers.Compose(); - - // create the factory - var factory = composition.CreateFactory(); - - // at that point Umbraco is fully composed - // but nothing is initialized (no maindom, nothing - beware!) - // to actually *run* Umbraco standalone, better use a StandaloneRuntime - // that would inherit from CoreRuntime and ensure everything starts - - // get components to initialize themselves - //components.Initialize(factory); - - // and then, validate - var lightInjectContainer = (LightInject.ServiceContainer) factory.Concrete; - var results = lightInjectContainer.Validate().ToList(); - foreach (var resultGroup in results.GroupBy(x => x.Severity).OrderBy(x => x.Key)) - { - Console.WriteLine($"{resultGroup.Key}: {resultGroup.Count()}"); - } - - foreach (var resultGroup in results.GroupBy(x => x.Severity).OrderBy(x => x.Key)) - foreach (var result in resultGroup) - { - Console.WriteLine(); - Console.Write(result.ToText()); - } - - Assert.AreEqual(0, results.Count); - } - - - - - } -} diff --git a/src/Umbraco.Tests/Services/PerformanceTests.cs b/src/Umbraco.Tests/Services/PerformanceTests.cs deleted file mode 100644 index da33685bdd..0000000000 --- a/src/Umbraco.Tests/Services/PerformanceTests.cs +++ /dev/null @@ -1,308 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading; -using Microsoft.Extensions.Logging.Abstractions; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Web.Composing; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Services.Implement; -using Umbraco.Tests.LegacyXmlPublishedCache; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; -using Umbraco.Tests.TestHelpers.Stubs; -using Umbraco.Tests.Testing; - -namespace Umbraco.Tests.Services -{ - /// - /// Tests covering all methods in the ContentService class. - /// This is more of an integration test as it involves multiple layers - /// as well as configuration. - /// - [TestFixture] - [Apartment(ApartmentState.STA)] - [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - [NUnit.Framework.Explicit("These should not be run by the server, only directly as they are only benchmark tests")] - public class PerformanceTests : TestWithDatabaseBase - { - protected override string GetDbConnectionString() - { - return @"server=.\SQLEXPRESS;database=UmbTest;user id=sa;password=test"; - } - - protected override string GetDbProviderName() - { - return Constants.DbProviderNames.SqlServer; - } - - - /// - /// don't create anything, we're testing against our own server - /// - protected override void CreateSqlCeDatabase() - { - } - - [TearDown] - public override void TearDown() - { - base.TearDown(); - } - - private static IProfilingLogger GetTestProfilingLogger() - { - var profiler = new TestProfiler(); - return new ProfilingLogger(new NullLogger(), profiler); - } - - [Test] - public void Get_All_Published_Content() - { - var result = PrimeDbWithLotsOfContent(); - var contentSvc = (ContentService) ServiceContext.ContentService; - - var countOfPublished = result.Count(x => x.Published); - var contentTypeId = result.First().ContentTypeId; - - var proflog = GetTestProfilingLogger(); - using (proflog.DebugDuration("Getting published content normally")) - { - //do this 10x! - for (var i = 0; i < 10; i++) - { - - var published = new List(); - //get all content items that are published - var rootContent = contentSvc.GetRootContent(); - foreach (var content in rootContent.Where(content => content.Published)) - { - published.Add(content); - published.AddRange(contentSvc.GetPublishedDescendants(content)); - } - Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId)); - } - - } - - using (proflog.DebugDuration("Getting published content optimized")) - { - - //do this 10x! - for (var i = 0; i < 10; i++) - { - - //get all content items that are published - var published = contentSvc.GetAllPublished(); - - Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId)); - } - } - } - - - [Test] - public void Truncate_Insert_Vs_Update_Insert() - { - var customObjectType = Guid.NewGuid(); - //chuck lots of data in the db - var nodes = PrimeDbWithLotsOfContentXmlRecords(customObjectType); - var proflog = GetTestProfilingLogger(); - - //now we need to test the difference between truncating all records and re-inserting them as we do now, - //vs updating them (which might result in checking if they exist for or listening on an exception). - using (proflog.DebugDuration("Starting truncate + normal insert test")) - using (var scope = ScopeProvider.CreateScope()) - { - //do this 10x! - for (var i = 0; i < 10; i++) - { - //clear all the xml entries - scope.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN - (SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml - INNER JOIN cmsContent ON cmsContentXml.nodeId = cmsContent.nodeId)"); - - //now we insert each record for the ones we've deleted like we do in the content service. - var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = UpdatedXmlStructure }).ToList(); - foreach (var xml in xmlItems) - { - var result = scope.Database.Insert(xml); - } - } - - scope.Complete(); - } - - //now, isntead of truncating, we'll attempt to update and if it doesn't work then we insert - using (proflog.DebugDuration("Starting update test")) - using (var scope = ScopeProvider.CreateScope()) - { - //do this 10x! - for (var i = 0; i < 10; i++) - { - //now we insert each record for the ones we've deleted like we do in the content service. - var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = UpdatedXmlStructure }).ToList(); - foreach (var xml in xmlItems) - { - var result = scope.Database.Update(xml); - } - } - - scope.Complete(); - } - - //now, test truncating but then do bulk insertion of records - using (proflog.DebugDuration("Starting truncate + bulk insert test in one transaction")) - using (var scope = ScopeProvider.CreateScope()) - { - //do this 10x! - for (var i = 0; i < 10; i++) - { - //now we insert each record for the ones we've deleted like we do in the content service. - var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = UpdatedXmlStructure }).ToList(); - - //clear all the xml entries - scope.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN - (SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml - INNER JOIN cmsContent ON cmsContentXml.nodeId = cmsContent.nodeId)"); - - - scope.Database.BulkInsertRecords(xmlItems); - } - - scope.Complete(); - } - } - - private IEnumerable PrimeDbWithLotsOfContent() - { - var contentType1 = MockedContentTypes.CreateSimpleContentType(); - contentType1.AllowedAsRoot = true; - ServiceContext.ContentTypeService.Save(contentType1); - contentType1.AllowedContentTypes = new List - { - new ContentTypeSort(new Lazy(() => contentType1.Id), 0, contentType1.Alias) - }; - var result = new List(); - ServiceContext.ContentTypeService.Save(contentType1); - IContent lastParent = MockedContent.CreateSimpleContent(contentType1); - lastParent.PublishCulture(CultureImpact.Invariant); - ServiceContext.ContentService.SaveAndPublish(lastParent); - result.Add(lastParent); - //create 20 deep - for (var i = 0; i < 20; i++) - { - //for each level, create 20 - IContent content = null; - for (var j = 1; j <= 10; j++) - { - content = MockedContent.CreateSimpleContent(contentType1, "Name" + j, lastParent); - //only publish evens - if (j % 2 == 0) - { - content.PublishCulture(CultureImpact.Invariant); - ServiceContext.ContentService.SaveAndPublish(content); - } - else - { - ServiceContext.ContentService.Save(content); - } - result.Add(content); - } - - //assign the last one as the next parent - lastParent = content; - } - return result; - } - - private IEnumerable PrimeDbWithLotsOfContentXmlRecords(Guid customObjectType) - { - var nodes = new List(); - for (var i = 1; i < 10000; i++) - { - nodes.Add(new NodeDto - { - Level = 1, - ParentId = -1, - NodeObjectType = customObjectType, - Text = i.ToString(CultureInfo.InvariantCulture), - UserId = -1, - CreateDate = DateTime.Now, - Trashed = false, - SortOrder = 0, - Path = "" - }); - } - - using (var scope = ScopeProvider.CreateScope()) - { - scope.Database.BulkInsertRecords(nodes); - - //re-get the nodes with ids - var sql = Current.SqlContext.Sql(); - sql.SelectAll().From().Where(x => x.NodeObjectType == customObjectType); - nodes = scope.Database.Fetch(sql); - - //create the cmsContent data, each with a new content type id (so we can query on it later if needed) - var contentTypeId = 0; - var cmsContentItems = nodes.Select(node => new ContentDto { NodeId = node.NodeId, ContentTypeId = contentTypeId++ }).ToList(); - scope.Database.BulkInsertRecords(cmsContentItems); - - //create the xml data - var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = TestXmlStructure }).ToList(); - scope.Database.BulkInsertRecords(xmlItems); - - scope.Complete(); - } - - return nodes; - } - - private const string TestXmlStructure = @" - 0 - Standard Site for Umbraco by Koiak - - - - Built by Creative Founds -

Web ApplicationsCreative Founds design and build first class software solutions that deliver big results. We provide ASP.NET web and mobile applications, Umbraco development service & technical consultancy.

-

www.creativefounds.co.uk

]]>
- Umbraco Development -

UmbracoUmbraco the the leading ASP.NET open source CMS, under pinning over 150,000 websites. Our Certified Developers are experts in developing high performance and feature rich websites.

]]>
- Contact Us -

Contact Us on TwitterWe'd love to hear how this package has helped you and how it can be improved. Get in touch on the project website or via twitter

]]>
- -
Standard Website MVC, Company Address, Glasgow, Postcode
- Copyright &copy; 2012 Your Company - http://www.umbraco.org - /media/1477/umbraco_logo.png - - - - - - - 2013-07-01T00:00:00 -
"; - - private const string UpdatedXmlStructure = @" - 0 - - - - Clients -

This is a standard content page.

-

Vestibulum malesuada aliquet ante, vitae ullamcorper felis faucibus vel. Vestibulum condimentum faucibus tellus porta ultrices. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

-

Cras at auctor orci. Praesent facilisis erat nec odio consequat at posuere ligula pretium. Nulla eget felis id nisl volutpat pellentesque. Ut id augue id ligula placerat rutrum a nec purus. Maecenas sed lectus ac mi pellentesque luctus quis sit amet turpis. Vestibulum adipiscing convallis vestibulum.

-

Duis condimentum lectus at orci placerat vitae imperdiet lorem cursus. Duis hendrerit porta lorem, non suscipit quam consectetur vitae. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean elit augue, tincidunt nec tincidunt id, elementum vel est.

]]>
- -
"; - - } -} diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 616bfa96b6..526e1aa252 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -130,27 +130,22 @@ - - - - - - + + - @@ -167,16 +162,12 @@ - - - - @@ -187,9 +178,7 @@ - - @@ -203,17 +192,13 @@ - - - - @@ -222,9 +207,6 @@ - - - @@ -235,32 +217,17 @@ - - - - - - - - - - - - - - - @@ -271,14 +238,8 @@ - - - - - - @@ -286,32 +247,12 @@ - - - - - - - - - - - - - - - - - - - - @@ -319,9 +260,7 @@ True ImportResources.resx - - @@ -427,12 +366,6 @@ - - Always - - - PreserveNewest - diff --git a/src/Umbraco.Tests/Web/Mvc/RenderModelBinderTests.cs b/src/Umbraco.Tests/Web/Mvc/RenderModelBinderTests.cs deleted file mode 100644 index aa94272964..0000000000 --- a/src/Umbraco.Tests/Web/Mvc/RenderModelBinderTests.cs +++ /dev/null @@ -1,181 +0,0 @@ -using System.Collections.Generic; -using System.Globalization; -using System.Web; -using System.Web.Mvc; -using System.Web.Routing; -using Moq; -using NUnit.Framework; -using Umbraco.Core.Models; -using Umbraco.Core.Models.PublishedContent; -using Umbraco.Tests.Common; -using Umbraco.Tests.TestHelpers.Stubs; -using Umbraco.Web.Models; -using Umbraco.Web.Mvc; -using Current = Umbraco.Web.Composing.Current; - -namespace Umbraco.Tests.Web.Mvc -{ - [TestFixture] - public class RenderModelBinderTests - { - [SetUp] - public void SetUp() - { - Current.UmbracoContextAccessor = new TestUmbracoContextAccessor(); - } - - [TearDown] - public void TearDown() - { - Current.Reset(); - } - - [Test] - public void Returns_Binder_For_IPublishedContent_And_IRenderModel() - { - var binder = ContentModelBinder.Instance; - var found = binder.GetBinder(typeof (IPublishedContent)); - Assert.IsNotNull(found); - found = binder.GetBinder(typeof(ContentModel)); - Assert.IsNotNull(found); - found = binder.GetBinder(typeof(MyContent)); - Assert.IsNotNull(found); - found = binder.GetBinder(typeof(ContentModel)); - Assert.IsNotNull(found); - - found = binder.GetBinder(typeof(MyOtherContent)); - Assert.IsNull(found); - found = binder.GetBinder(typeof(MyCustomContentModel)); - Assert.IsNull(found); - found = binder.GetBinder(typeof(IContentModel)); - Assert.IsNull(found); - } - - [Test] - public void BindModel_Null_Source_Returns_Null() - { - Assert.IsNull(ContentModelBinder.BindModel(null, typeof(MyContent))); - } - - [Test] - public void BindModel_Returns_If_Same_Type() - { - var content = new MyContent(Mock.Of()); - var bound = ContentModelBinder.BindModel(content, typeof (IPublishedContent)); - Assert.AreSame(content, bound); - } - - [Test] - public void BindModel_RenderModel_To_IPublishedContent() - { - var content = new MyContent(Mock.Of()); - var renderModel = new ContentModel(content); - var bound = ContentModelBinder.BindModel(renderModel, typeof(IPublishedContent)); - Assert.AreSame(content, bound); - } - - [Test] - public void BindModel_IPublishedContent_To_RenderModel() - { - var content = new MyContent(Mock.Of()); - var bound = (IContentModel)ContentModelBinder.BindModel(content, typeof(ContentModel)); - Assert.AreSame(content, bound.Content); - } - - [Test] - public void BindModel_IPublishedContent_To_Generic_RenderModel() - { - var content = new MyContent(Mock.Of()); - var bound = (IContentModel)ContentModelBinder.BindModel(content, typeof(ContentModel)); - Assert.AreSame(content, bound.Content); - } - - [Test] - public void No_DataToken_Returns_Null() - { - var binder = ContentModelBinder.Instance; - var routeData = new RouteData(); - var result = binder.BindModel(new ControllerContext(Mock.Of(), routeData, Mock.Of()), - new ModelBindingContext()); - - Assert.IsNull(result); - } - - [Test] - public void Invalid_DataToken_Model_Type_Returns_Null() - { - var binder = ContentModelBinder.Instance; - var routeData = new RouteData(); - routeData.DataTokens[Core.Constants.Web.UmbracoDataToken] = "hello"; - - //the value provider is the default implementation - var valueProvider = new Mock(); - //also IUnvalidatedValueProvider - var invalidatedValueProvider = valueProvider.As(); - invalidatedValueProvider.Setup(x => x.GetValue(It.IsAny(), It.IsAny())).Returns(() => - new ValueProviderResult(null, "", CultureInfo.CurrentCulture)); - - var controllerCtx = new ControllerContext( - Mock.Of(http => http.Items == new Dictionary()), - routeData, - Mock.Of()); - - var result = binder.BindModel(controllerCtx, - new ModelBindingContext - { - ValueProvider = valueProvider.Object, - ModelMetadata = new ModelMetadata(new EmptyModelMetadataProvider(), null, () => null, typeof(IPublishedContent), "content") - }); - - Assert.IsNull(result); - } - - [Test] - public void IPublishedContent_DataToken_Model_Type_Uses_DefaultImplementation() - { - var content = new MyContent(Mock.Of()); - var binder = ContentModelBinder.Instance; - var routeData = new RouteData(); - routeData.DataTokens[Core.Constants.Web.UmbracoDataToken] = content; - - //the value provider is the default implementation - var valueProvider = new Mock(); - //also IUnvalidatedValueProvider - var invalidatedValueProvider = valueProvider.As(); - invalidatedValueProvider.Setup(x => x.GetValue(It.IsAny(), It.IsAny())).Returns(() => - new ValueProviderResult(content, "content", CultureInfo.CurrentCulture)); - - var controllerCtx = new ControllerContext( - Mock.Of(http => http.Items == new Dictionary()), - routeData, - Mock.Of()); - var result = binder.BindModel(controllerCtx, - new ModelBindingContext - { - ValueProvider = valueProvider.Object, - ModelMetadata = new ModelMetadata(new EmptyModelMetadataProvider(), null, () => null, typeof(IPublishedContent), "content") - }); - - Assert.AreEqual(content, result); - } - - public class MyCustomContentModel : ContentModel - { - public MyCustomContentModel(IPublishedContent content) - : base(content) - { } - } - - public class MyOtherContent - { - - } - - public class MyContent : PublishedContentWrapped - { - public MyContent(IPublishedContent content) : base(content) - { - } - } - } -} diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs deleted file mode 100644 index c7ab297076..0000000000 --- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs +++ /dev/null @@ -1,466 +0,0 @@ -using System; -using System.Globalization; -using System.Web.Mvc; -using System.Web.Routing; -using Microsoft.Extensions.Logging.Abstractions; -using Moq; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.Models; -using Umbraco.Core.Models.PublishedContent; -using Umbraco.Core.Services; -using Umbraco.Tests.Common; -using Umbraco.Tests.LegacyXmlPublishedCache; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.Testing; -using Umbraco.Web; -using Umbraco.Web.Composing; -using Umbraco.Web.Models; -using Umbraco.Web.Mvc; -using Umbraco.Web.Routing; -using Umbraco.Web.Security; - -namespace Umbraco.Tests.Web.Mvc -{ - [TestFixture] - [UmbracoTest(WithApplication = true)] - public class UmbracoViewPageTests : UmbracoTestBase - { - private XmlPublishedSnapshotService _service; - - [TearDown] - public override void TearDown() - { - if (_service == null) return; - _service.Dispose(); - _service = null; - } - - #region RenderModel To ... - - [Test] - public void RenderModel_To_RenderModel() - { - var content = new ContentType1(null); - var model = new ContentModel(content); - var view = new RenderModelTestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.AreSame(model, view.Model); - } - - [Test] - public void RenderModel_ContentType1_To_ContentType1() - { - var content = new ContentType1(null); - var model = new ContentModel(content); - var view = new ContentType1TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf(view.Model); - } - - [Test] - public void RenderModel_ContentType2_To_ContentType1() - { - var content = new ContentType2(null); - var model = new ContentModel(content); - var view = new ContentType1TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf(view.Model); - } - - [Test] - public void RenderModel_ContentType1_To_ContentType2() - { - var content = new ContentType1(null); - var model = new ContentModel(content); - var view = new ContentType2TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - - Assert.Throws(() => view.SetViewDataX(viewData)); - } - - [Test] - public void RenderModel_ContentType1_To_RenderModelOf_ContentType1() - { - var content = new ContentType1(null); - var model = new ContentModel(content); - var view = new RenderModelOfContentType1TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf>(view.Model); - Assert.IsInstanceOf(view.Model.Content); - } - - [Test] - public void RenderModel_ContentType2_To_RenderModelOf_ContentType1() - { - var content = new ContentType2(null); - var model = new ContentModel(content); - var view = new RenderModelOfContentType1TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf>(view.Model); - Assert.IsInstanceOf(view.Model.Content); - } - - [Test] - public void RenderModel_ContentType1_To_RenderModelOf_ContentType2() - { - var content = new ContentType1(null); - var model = new ContentModel(content); - var view = new RenderModelOfContentType2TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - - Assert.Throws(() => view.SetViewDataX(viewData)); - } - - #endregion - - #region RenderModelOf To ... - - [Test] - public void RenderModelOf_ContentType1_To_RenderModel() - { - var content = new ContentType1(null); - var model = new ContentModel(content); - var view = new RenderModelTestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.AreSame(model, view.Model); - } - - [Test] - public void RenderModelOf_ContentType1_To_ContentType1() - { - var content = new ContentType1(null); - var model = new ContentModel(content); - var view = new ContentType1TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf(view.Model); - } - - [Test] - public void RenderModelOf_ContentType2_To_ContentType1() - { - var content = new ContentType2(null); - var model = new ContentModel(content); - var view = new ContentType1TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf(view.Model); - } - - [Test] - public void RenderModelOf_ContentType1_To_ContentType2() - { - var content = new ContentType1(null); - var model = new ContentModel(content); - var view = new ContentType2TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - Assert.Throws(() => view.SetViewDataX(viewData)); - } - - [Test] - public void RenderModelOf_ContentType1_To_RenderModelOf_ContentType1() - { - var content = new ContentType1(null); - var model = new ContentModel(content); - var view = new RenderModelOfContentType1TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf>(view.Model); - Assert.IsInstanceOf(view.Model.Content); - } - - [Test] - public void RenderModelOf_ContentType2_To_RenderModelOf_ContentType1() - { - var content = new ContentType2(null); - var model = new ContentModel(content); - var view = new RenderModelOfContentType1TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf>(view.Model); - Assert.IsInstanceOf(view.Model.Content); - } - - [Test] - public void RenderModelOf_ContentType1_To_RenderModelOf_ContentType2() - { - var content = new ContentType1(null); - var model = new ContentModel(content); - var view = new RenderModelOfContentType2TestPage(); - var viewData = new ViewDataDictionary(model); - - view.ViewContext = GetViewContext(); - Assert.Throws(() => view.SetViewDataX(viewData)); - } - - #endregion - - #region ContentType To ... - - [Test] - public void ContentType1_To_RenderModel() - { - var content = new ContentType1(null); - var view = new RenderModelTestPage(); - var viewData = new ViewDataDictionary(content); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf(view.Model); - } - - [Test] - public void ContentType1_To_RenderModelOf_ContentType1() - { - var content = new ContentType1(null); - var view = new RenderModelOfContentType1TestPage(); - var viewData = new ViewDataDictionary(content); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf>(view.Model); - Assert.IsInstanceOf(view.Model.Content); - } - - [Test] - public void ContentType2_To_RenderModelOf_ContentType1() - { - var content = new ContentType2(null); - var view = new RenderModelOfContentType1TestPage(); - var viewData = new ViewDataDictionary(content); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf>(view.Model); - Assert.IsInstanceOf(view.Model.Content); - } - - [Test] - public void ContentType1_To_RenderModelOf_ContentType2() - { - var content = new ContentType1(null); - var view = new RenderModelOfContentType2TestPage(); - var viewData = new ViewDataDictionary(content); - - view.ViewContext = GetViewContext(); - Assert.Throws(() =>view.SetViewDataX(viewData)); - } - - [Test] - public void ContentType1_To_ContentType1() - { - var content = new ContentType1(null); - var view = new ContentType1TestPage(); - var viewData = new ViewDataDictionary(content); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf(view.Model); - } - - [Test] - public void ContentType1_To_ContentType2() - { - var content = new ContentType1(null); - var view = new ContentType2TestPage(); - var viewData = new ViewDataDictionary(content); - - view.ViewContext = GetViewContext(); - Assert.Throws(() => view.SetViewDataX(viewData)); - } - - [Test] - public void ContentType2_To_ContentType1() - { - var content = new ContentType2(null); - var view = new ContentType1TestPage(); - var viewData = new ViewDataDictionary(content); - - view.ViewContext = GetViewContext(); - view.SetViewDataX(viewData); - - Assert.IsInstanceOf(view.Model); - } - - #endregion - - #region Test elements - - public class TestPage : UmbracoViewPage - { - public override void Execute() - { - throw new NotImplementedException(); - } - - public void SetViewDataX(ViewDataDictionary viewData) - { - SetViewData(viewData); - } - } - - public class RenderModelTestPage : TestPage - { } - - public class RenderModelOfContentType1TestPage : TestPage> - { } - - public class RenderModelOfContentType2TestPage : TestPage> - { } - - public class ContentType1TestPage : TestPage - { } - - public class ContentType2TestPage : TestPage - { } - - public class ContentType1 : PublishedContentWrapped - { - public ContentType1(IPublishedContent content) : base(content) {} - } - - public class ContentType2 : ContentType1 - { - public ContentType2(IPublishedContent content) : base(content) { } - } - - #endregion - - #region Test helpers - - ServiceContext GetServiceContext() - { - return TestObjects.GetServiceContextMock(); - } - - ViewContext GetViewContext() - { - var umbracoContext = GetUmbracoContext("/dang", 0); - - var webRoutingSettings = new WebRoutingSettings(); - var publishedRouter = BaseWebTest.CreatePublishedRouter(webRoutingSettings); - var frequest = publishedRouter.CreateRequest(umbracoContext, new Uri("http://localhost/dang")); - - frequest.Culture = CultureInfo.InvariantCulture; - umbracoContext.PublishedRequest = frequest; - - var context = new ViewContext(); - context.RouteData = new RouteData(); - context.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbracoContext); - - return context; - } - - protected IUmbracoContext GetUmbracoContext(string url, int templateId, RouteData routeData = null, bool setSingleton = false) - { - var svcCtx = GetServiceContext(); - - var databaseFactory = TestObjects.GetDatabaseFactoryMock(); - - //var appCtx = new ApplicationContext( - // new DatabaseContext(databaseFactory, logger, Mock.Of(), Mock.Of()), - // svcCtx, - // CacheHelper.CreateDisabledCacheHelper(), - // new ProfilingLogger(logger, Mock.Of())) { /*IsReady = true*/ }; - - var cache = NoAppCache.Instance; - //var provider = new ScopeUnitOfWorkProvider(databaseFactory, new RepositoryFactory(Mock.Of())); - var scopeProvider = TestObjects.GetScopeProvider(NullLoggerFactory.Instance); - var factory = Mock.Of(); - var umbracoContextAccessor = Mock.Of(); - _service = new XmlPublishedSnapshotService(svcCtx, factory, scopeProvider, cache, - null, null, - umbracoContextAccessor, null, null, null, - new TestDefaultCultureAccessor(), - Current.LoggerFactory, TestObjects.GetGlobalSettings(), - TestHelper.GetHostingEnvironment(), - TestHelper.GetHostingEnvironmentLifetime(), - ShortStringHelper, - new SiteDomainHelper(), - Factory.GetInstance(), - null, true, false - ); // no events - - var http = GetHttpContextFactory(url, routeData).HttpContext; - - var httpContextAccessor = TestHelper.GetHttpContextAccessor(http); - var globalSettings = TestObjects.GetGlobalSettings(); - - var ctx = new UmbracoContext( - httpContextAccessor, - _service, - Mock.Of(), - globalSettings, - HostingEnvironment, - new TestVariationContextAccessor(), - UriUtility, - new AspNetCookieManager(httpContextAccessor)); - - //if (setSingleton) - //{ - // UmbracoContext.Current = ctx; - //} - - return ctx; - } - - protected FakeHttpContextFactory GetHttpContextFactory(string url, RouteData routeData = null) - { - var factory = routeData != null - ? new FakeHttpContextFactory(url, routeData) - : new FakeHttpContextFactory(url); - - return factory; - } - - #endregion - } -} diff --git a/src/Umbraco.Web.BackOffice/ActionResults/JavaScriptResult.cs b/src/Umbraco.Web.BackOffice/ActionResults/JavaScriptResult.cs index a34c6c6abd..d440cc833d 100644 --- a/src/Umbraco.Web.BackOffice/ActionResults/JavaScriptResult.cs +++ b/src/Umbraco.Web.BackOffice/ActionResults/JavaScriptResult.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; -namespace Umbraco.Web.Common.ActionResults +namespace Umbraco.Web.BackOffice.ActionResults { public class JavaScriptResult : ContentResult { diff --git a/src/Umbraco.Web.BackOffice/ActionResults/UmbracoErrorResult.cs b/src/Umbraco.Web.BackOffice/ActionResults/UmbracoErrorResult.cs index 8f77977535..e810fb1eb3 100644 --- a/src/Umbraco.Web.BackOffice/ActionResults/UmbracoErrorResult.cs +++ b/src/Umbraco.Web.BackOffice/ActionResults/UmbracoErrorResult.cs @@ -1,7 +1,7 @@ using System.Net; using Microsoft.AspNetCore.Mvc; -namespace Umbraco.Web.Common.ActionResults +namespace Umbraco.Web.BackOffice.ActionResults { public class UmbracoErrorResult : ObjectResult { diff --git a/src/Umbraco.Web.BackOffice/ActionResults/UmbracoNotificationSuccessResponse.cs b/src/Umbraco.Web.BackOffice/ActionResults/UmbracoNotificationSuccessResponse.cs index c1e0e8c601..cdd9359ac1 100644 --- a/src/Umbraco.Web.BackOffice/ActionResults/UmbracoNotificationSuccessResponse.cs +++ b/src/Umbraco.Web.BackOffice/ActionResults/UmbracoNotificationSuccessResponse.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Umbraco.Web.Models.ContentEditing; -namespace Umbraco.Web.Common.ActionResults +namespace Umbraco.Web.BackOffice.ActionResults { public class UmbracoNotificationSuccessResponse : OkObjectResult { diff --git a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs index a6b350da91..511254e96b 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Net; -using System.Net.Mail; using System.Threading.Tasks; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authentication; @@ -310,6 +309,7 @@ namespace Umbraco.Web.BackOffice.Controllers var user = _userService.GetByEmail(model.Email); if (user != null) { + var from = _globalSettings.Smtp.From; var code = await _userManager.GeneratePasswordResetTokenAsync(identityUser); var callbackUrl = ConstructCallbackUrl(identityUser.Id, code); @@ -322,13 +322,7 @@ namespace Umbraco.Web.BackOffice.Controllers // Ensure the culture of the found user is used for the email! UmbracoUserExtensions.GetUserCulture(identityUser.Culture, _textService, _globalSettings)); - var mailMessage = new MailMessage() - { - Subject = subject, - Body = message, - IsBodyHtml = true, - To = { user.Email } - }; + var mailMessage = new EmailMessage(from, user.Email, subject, message, true); await _emailSender.SendAsync(mailMessage); diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs index b87b5d0fbb..99eae2c459 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs @@ -20,8 +20,8 @@ using Umbraco.Core.Serialization; using Umbraco.Core.Services; using Umbraco.Core.WebAssets; using Umbraco.Extensions; +using Umbraco.Web.BackOffice.ActionResults; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.Common.ActionResults; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Filters; using Umbraco.Web.Common.Security; @@ -32,6 +32,7 @@ using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.BackOffice.Controllers { + [DisableBrowserCache] //TODO Reintroduce //[UmbracoRequireHttps] //TODO Reintroduce [PluginController(Constants.Web.Mvc.BackOfficeArea)] public class BackOfficeController : UmbracoController diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeNotificationsController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeNotificationsController.cs index 6bb6e87a5e..5c6a999e4a 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeNotificationsController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeNotificationsController.cs @@ -1,5 +1,4 @@ using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.WebApi.Filters; namespace Umbraco.Web.BackOffice.Controllers { diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs index 9f109d7bbf..62d26f1e25 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs @@ -14,10 +14,12 @@ using Umbraco.Core.Hosting; using Umbraco.Core.Media; using Umbraco.Core.WebAssets; using Umbraco.Extensions; +using Umbraco.Web.BackOffice.HealthCheck; using Umbraco.Web.BackOffice.Profiling; using Umbraco.Web.BackOffice.PropertyEditors; using Umbraco.Web.BackOffice.Routing; -using Umbraco.Web.Common.Attributes; + using Umbraco.Web.BackOffice.Trees; + using Umbraco.Web.Common.Attributes; using Umbraco.Web.Editors; using Umbraco.Web.Features; using Umbraco.Web.Models.ContentEditing; diff --git a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs index 0a3d3c47a7..6dd7164520 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs @@ -31,12 +31,12 @@ using Constants = Umbraco.Core.Constants; using Umbraco.Extensions; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.BackOffice.ModelBinders; -using Umbraco.Web.Common.ActionResults; +using Umbraco.Web.BackOffice.ActionResults; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Common.Filters; using Umbraco.Web.Models.Mapping; -using Umbraco.Web.WebApi.Filters; + namespace Umbraco.Web.BackOffice.Controllers { diff --git a/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs b/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs index 5bf6798170..19b58942fd 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs @@ -33,12 +33,11 @@ using Umbraco.Core.Strings; using Umbraco.Extensions; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.BackOffice.ModelBinders; -using Umbraco.Web.Common.ActionResults; +using Umbraco.Web.BackOffice.ActionResults; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; using Umbraco.Web.ContentApps; using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.WebApi.Filters; using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.BackOffice.Controllers diff --git a/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs b/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs index fd4d5c96cc..82321e7e12 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs @@ -32,7 +32,6 @@ using Umbraco.Web.Common.Filters; using Umbraco.Web.ContentApps; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Security; -using Umbraco.Web.WebApi.Filters; using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.BackOffice.Controllers diff --git a/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs b/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs index fb6d597d9e..07e3cb13da 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs @@ -15,7 +15,7 @@ using Umbraco.Core.Services; using Umbraco.Core.WebAssets; using Umbraco.Extensions; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.Common.ActionResults; +using Umbraco.Web.BackOffice.ActionResults; using Umbraco.Web.Common.Filters; using Umbraco.Web.Editors; using Umbraco.Web.Features; diff --git a/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs b/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs index 982dab6dec..cf3ed37f30 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs @@ -8,12 +8,12 @@ using Umbraco.Core.Models; using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Controllers; +using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Models.Trees; using Umbraco.Web.Security; using Umbraco.Web.Services; -using Umbraco.Web.Trees; namespace Umbraco.Web.BackOffice.Controllers { diff --git a/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs b/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs index 6d641c9cf9..18cb4b8afe 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs @@ -10,7 +10,7 @@ using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.Common.ActionResults; +using Umbraco.Web.BackOffice.ActionResults; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Models.ContentEditing; diff --git a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs index d45951a3df..82c2d4d245 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; -using System.Net.Mail; using System.Runtime.Serialization; using System.Security.Cryptography; using System.Threading.Tasks; @@ -29,12 +28,11 @@ using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Web.Models; using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.WebApi.Filters; using Umbraco.Extensions; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.BackOffice.ModelBinders; using Umbraco.Web.BackOffice.Security; -using Umbraco.Web.Common.ActionResults; +using Umbraco.Web.BackOffice.ActionResults; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Editors; @@ -543,13 +541,7 @@ namespace Umbraco.Web.BackOffice.Controllers UmbracoUserExtensions.GetUserCulture(to.Language, _localizedTextService, _globalSettings), new[] { userDisplay.Name, from, message, inviteUri.ToString(), fromEmail }); - var mailMessage = new MailMessage() - { - Subject = emailSubject, - Body = emailBody, - IsBodyHtml = true, - To = { to.Email} - }; + var mailMessage = new EmailMessage(fromEmail, to.Email, emailSubject, emailBody, true); await _emailSender.SendAsync(mailMessage); } diff --git a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeApplicationBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/BackOfficeApplicationBuilderExtensions.cs index 3c6b538506..8b38211794 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/BackOfficeApplicationBuilderExtensions.cs @@ -1,7 +1,13 @@ using System; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using SixLabors.ImageSharp.Web.DependencyInjection; +using Umbraco.Composing; +using Umbraco.Core; +using Umbraco.Core.Configuration.Models; +using Umbraco.Core.IO; using Umbraco.Web.BackOffice.Routing; using Umbraco.Web.BackOffice.Security; @@ -23,6 +29,18 @@ namespace Umbraco.Extensions app.UseUmbracoPreview(); app.UseUmbracoInstaller(); + + // TODO: remove current class, it's on its last legs. + Current.Initialize( + app.ApplicationServices.GetService>(), + app.ApplicationServices.GetService>().Value, + app.ApplicationServices.GetService>().Value, + app.ApplicationServices.GetService(), + app.ApplicationServices.GetService(), + app.ApplicationServices.GetService(), + app.ApplicationServices.GetService() + ); + return app; } diff --git a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs index 71fa97b9cb..8ca1de2987 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs @@ -14,6 +14,7 @@ using Umbraco.Core.BackOffice; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Security; using Umbraco.Core.Serialization; +using Umbraco.Infrastructure.BackOffice; using Umbraco.Net; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.BackOffice.Security; @@ -72,7 +73,7 @@ namespace Umbraco.Extensions services.ConfigureOptions(); } - private static IdentityBuilder BuildUmbracoBackOfficeIdentity(this IServiceCollection services) + private static BackOfficeIdentityBuilder BuildUmbracoBackOfficeIdentity(this IServiceCollection services) { // Borrowed from https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Extensions.Core/src/IdentityServiceCollectionExtensions.cs#L33 // The reason we need our own is because the Identity system doesn't cater easily for multiple identity systems and particularly being @@ -96,7 +97,7 @@ namespace Umbraco.Extensions services.TryAddScoped(); services.TryAddScoped(); - return new IdentityBuilder(typeof(BackOfficeIdentityUser), services); + return new BackOfficeIdentityBuilder(services); } } } diff --git a/src/Umbraco.Web.BackOffice/Extensions/CompositionExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/CompositionExtensions.cs index 5cc481c018..198f98e3c0 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/CompositionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/CompositionExtensions.cs @@ -1,5 +1,8 @@ using Umbraco.Core.Composing; -using Umbraco.Web.Trees; +using Umbraco.Web.BackOffice.Controllers; +using Umbraco.Web.Common.Controllers; +using Umbraco.Web.Common.Install; +using Umbraco.Web.BackOffice.Trees; // the namespace here is intentional - although defined in Umbraco.Web assembly, // this class should be visible when using Umbraco.Core.Components, alongside @@ -25,5 +28,25 @@ namespace Umbraco.Extensions #endregion + + /// + /// Registers Umbraco backoffice controllers. + /// + public static Composition ComposeUmbracoBackOfficeControllers(this Composition composition) + { + composition.RegisterControllers(new [] + { + typeof(BackOfficeController), + typeof(PreviewController), + typeof(AuthenticationController), + typeof(InstallController), + typeof(InstallApiController), + }); + + var umbracoAuthorizedApiControllers = composition.TypeLoader.GetTypes(); + composition.RegisterControllers(umbracoAuthorizedApiControllers); + + return composition; + } } } diff --git a/src/Umbraco.Web.BackOffice/Extensions/ModelStateExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/ModelStateExtensions.cs index 01af08fb90..c798a00dd1 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/ModelStateExtensions.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/ModelStateExtensions.cs @@ -4,7 +4,7 @@ using System.Linq; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ModelBinding; using Umbraco.Core; -using Umbraco.Web.PropertyEditors.Validation; +using Umbraco.Web.BackOffice.PropertyEditors.Validation; namespace Umbraco.Extensions { diff --git a/src/Umbraco.Web.BackOffice/Extensions/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/UmbracoBuilderExtensions.cs index a1a671527a..6a6a896bae 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/UmbracoBuilderExtensions.cs @@ -4,9 +4,9 @@ namespace Umbraco.Extensions { public static class UmbracoBuilderExtensions { - public static void BuildWithAllBackOfficeComponents(this IUmbracoBuilder builder) + public static IUmbracoBuilder WithAllBackOfficeComponents(this IUmbracoBuilder builder) { - builder + return builder .WithConfiguration() .WithCore() .WithWebComponents() @@ -16,8 +16,7 @@ namespace Umbraco.Extensions .WithMiniProfiler() .WithMvcAndRazor() .WithWebServer() - .WithPreview() - .Build(); + .WithPreview(); } public static IUmbracoBuilder WithBackOffice(this IUmbracoBuilder builder) diff --git a/src/Umbraco.Web.BackOffice/Extensions/WebMappingProfiles.cs b/src/Umbraco.Web.BackOffice/Extensions/WebMappingProfiles.cs index 501644246c..71d3481edf 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/WebMappingProfiles.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/WebMappingProfiles.cs @@ -2,7 +2,7 @@ using Umbraco.Core.BackOffice; using Umbraco.Core.Composing; using Umbraco.Core.Mapping; -using Umbraco.Web.Models.Mapping; +using Umbraco.Web.BackOffice.Mapping; namespace Umbraco.Extensions { diff --git a/src/Umbraco.Web.BackOffice/Filters/AppendCurrentEventMessagesAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/AppendCurrentEventMessagesAttribute.cs index 23377c8651..082d7c5e52 100644 --- a/src/Umbraco.Web.BackOffice/Filters/AppendCurrentEventMessagesAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/AppendCurrentEventMessagesAttribute.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Mvc.Filters; using Umbraco.Core.Events; using Umbraco.Web.Models.ContentEditing; -namespace Umbraco.Web.WebApi.Filters +namespace Umbraco.Web.BackOffice.Filters { /// /// Automatically checks if any request is a non-GET and if the diff --git a/src/Umbraco.Web.BackOffice/Filters/DataTypeValidateAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/DataTypeValidateAttribute.cs index 83b2bde0e5..b67cd17afc 100644 --- a/src/Umbraco.Web.BackOffice/Filters/DataTypeValidateAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/DataTypeValidateAttribute.cs @@ -13,7 +13,7 @@ using Umbraco.Web.Common.ActionsResults; using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Models.ContentEditing; -namespace Umbraco.Web.Editors +namespace Umbraco.Web.BackOffice.Filters { /// /// An attribute/filter that wires up the persisted entity of the DataTypeSave model and validates the whole request diff --git a/src/Umbraco.Web.BackOffice/Filters/EditorModelEventManager.cs b/src/Umbraco.Web.BackOffice/Filters/EditorModelEventManager.cs index 7255c91f49..d1856ee7d9 100644 --- a/src/Umbraco.Web.BackOffice/Filters/EditorModelEventManager.cs +++ b/src/Umbraco.Web.BackOffice/Filters/EditorModelEventManager.cs @@ -2,9 +2,10 @@ using Microsoft.AspNetCore.Mvc.Filters; using Umbraco.Core.Dashboards; using Umbraco.Core.Events; +using Umbraco.Web.Editors; using Umbraco.Web.Models.ContentEditing; -namespace Umbraco.Web.Editors +namespace Umbraco.Web.BackOffice.Filters { /// /// Used to emit events for editor models in the back office diff --git a/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForMediaAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForMediaAttribute.cs index 3bf3bd8730..67199a2d44 100644 --- a/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForMediaAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForMediaAttribute.cs @@ -10,7 +10,7 @@ using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Editors; using Umbraco.Web.Security; -namespace Umbraco.Web.WebApi.Filters +namespace Umbraco.Web.BackOffice.Filters { /// /// Auth filter to check if the current user has access to the content item diff --git a/src/Umbraco.Web.BackOffice/Filters/FileUploadCleanupFilterAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/FileUploadCleanupFilterAttribute.cs index d008b2d536..042c20520d 100644 --- a/src/Umbraco.Web.BackOffice/Filters/FileUploadCleanupFilterAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/FileUploadCleanupFilterAttribute.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging; using Umbraco.Core; using Umbraco.Web.Models.ContentEditing; -namespace Umbraco.Web.WebApi.Filters +namespace Umbraco.Web.BackOffice.Filters { /// /// Checks if the parameter is IHaveUploadedFiles and then deletes any temporary saved files from file uploads diff --git a/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingMediaAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingMediaAttribute.cs index a6325e0650..2f805523ec 100644 --- a/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingMediaAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingMediaAttribute.cs @@ -13,7 +13,7 @@ using Umbraco.Core.Services; using Umbraco.Web.Security; -namespace Umbraco.Web.WebApi.Filters +namespace Umbraco.Web.BackOffice.Filters { /// /// This inspects the result of the action that returns a collection of content and removes diff --git a/src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResultAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResultAttribute.cs index 65c2be051f..343a642d5b 100644 --- a/src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResultAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResultAttribute.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc.Filters; using Umbraco.Core.Hosting; using Microsoft.Extensions.DependencyInjection; using Umbraco.Core.WebAssets; -using Umbraco.Web.Common.ActionResults; +using Umbraco.Web.BackOffice.ActionResults; namespace Umbraco.Web.BackOffice.Filters { diff --git a/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs index 9952eb52f9..f8ba5efeff 100644 --- a/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs @@ -6,7 +6,7 @@ using Umbraco.Core.Security; using Umbraco.Web.Editors; using Umbraco.Web.Security; -namespace Umbraco.Web.WebApi.Filters +namespace Umbraco.Web.BackOffice.Filters { /// /// Used to emit outgoing editor model events diff --git a/src/Umbraco.Web.BackOffice/Filters/SetAngularAntiForgeryTokensAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/SetAngularAntiForgeryTokensAttribute.cs index aaf23d1799..756a6cb383 100644 --- a/src/Umbraco.Web.BackOffice/Filters/SetAngularAntiForgeryTokensAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/SetAngularAntiForgeryTokensAttribute.cs @@ -7,7 +7,7 @@ using Umbraco.Core; using Umbraco.Core.Configuration.Models; using Umbraco.Web.BackOffice.Security; -namespace Umbraco.Extensions +namespace Umbraco.Web.BackOffice.Filters { /// /// An attribute/filter to set the csrf cookie token based on angular conventions diff --git a/src/Umbraco.Web.BackOffice/Filters/UserGroupValidateAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/UserGroupValidateAttribute.cs index 2767af4ba2..8c6e85a44c 100644 --- a/src/Umbraco.Web.BackOffice/Filters/UserGroupValidateAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/UserGroupValidateAttribute.cs @@ -6,7 +6,7 @@ using Umbraco.Core; using Umbraco.Core.Mapping; using Umbraco.Core.Models.Membership; using Umbraco.Core.Services; -using Umbraco.Web.Common.ActionResults; +using Umbraco.Web.BackOffice.ActionResults; using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Models.ContentEditing; diff --git a/src/Umbraco.Web.BackOffice/HealthCheck/HealthCheckController.cs b/src/Umbraco.Web.BackOffice/HealthCheck/HealthCheckController.cs index 99535d3d30..768ede1787 100644 --- a/src/Umbraco.Web.BackOffice/HealthCheck/HealthCheckController.cs +++ b/src/Umbraco.Web.BackOffice/HealthCheck/HealthCheckController.cs @@ -2,16 +2,16 @@ using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc; -using Umbraco.Core; -using Umbraco.Core.Configuration.HealthChecks; -using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.HealthCheck; -using Umbraco.Web.Common.Attributes; -using Umbraco.Core.Configuration.Models; using Microsoft.Extensions.Options; +using Umbraco.Core; +using Umbraco.Core.Configuration.Models; +using Umbraco.Core.HealthCheck; +using Umbraco.Web.BackOffice.Controllers; +using Umbraco.Web.BackOffice.Filters; +using Umbraco.Web.Common.Attributes; using Microsoft.Extensions.Logging; -namespace Umbraco.Web.BackOffice.Controllers +namespace Umbraco.Web.BackOffice.HealthCheck { /// /// The API controller used to display the health check info and execute any actions @@ -85,7 +85,7 @@ namespace Umbraco.Web.BackOffice.Controllers return check.ExecuteAction(action); } - private HealthCheck.HealthCheck GetCheckById(Guid id) + private Core.HealthCheck.HealthCheck GetCheckById(Guid id) { var check = _checks .Where(x => _disabledCheckIds.Contains(x.Id) == false) diff --git a/src/Umbraco.Web.BackOffice/Mapping/CommonTreeNodeMapper.cs b/src/Umbraco.Web.BackOffice/Mapping/CommonTreeNodeMapper.cs index bd03ef9a88..794fd8caae 100644 --- a/src/Umbraco.Web.BackOffice/Mapping/CommonTreeNodeMapper.cs +++ b/src/Umbraco.Web.BackOffice/Mapping/CommonTreeNodeMapper.cs @@ -5,9 +5,9 @@ using Microsoft.AspNetCore.Routing; using Umbraco.Core.Models; using Umbraco.Extensions; using Umbraco.Web.Common.Controllers; -using Umbraco.Web.Trees; +using Umbraco.Web.BackOffice.Trees; -namespace Umbraco.Web.Models.Mapping +namespace Umbraco.Web.BackOffice.Mapping { public class CommonTreeNodeMapper { diff --git a/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs b/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs index 8124a91377..54e7006bec 100644 --- a/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs +++ b/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs @@ -10,10 +10,11 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Models.Membership; using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; +using Umbraco.Web.Models.Mapping; using Umbraco.Web.Routing; -using Umbraco.Web.Trees; +using Umbraco.Web.BackOffice.Trees; -namespace Umbraco.Web.Models.Mapping +namespace Umbraco.Web.BackOffice.Mapping { /// /// Declares how model mappings for content diff --git a/src/Umbraco.Web.BackOffice/Mapping/MediaMapDefinition.cs b/src/Umbraco.Web.BackOffice/Mapping/MediaMapDefinition.cs index 4076f01aab..3f8c308645 100644 --- a/src/Umbraco.Web.BackOffice/Mapping/MediaMapDefinition.cs +++ b/src/Umbraco.Web.BackOffice/Mapping/MediaMapDefinition.cs @@ -8,9 +8,10 @@ using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Trees; +using Umbraco.Web.Models.Mapping; +using Umbraco.Web.BackOffice.Trees; -namespace Umbraco.Web.Models.Mapping +namespace Umbraco.Web.BackOffice.Mapping { /// /// Declares model mappings for media. diff --git a/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs b/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs index aba2d4a12c..2df45704d8 100644 --- a/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs +++ b/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs @@ -3,9 +3,10 @@ using Umbraco.Core; using Umbraco.Core.Mapping; using Umbraco.Core.Models; using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Trees; +using Umbraco.Web.Models.Mapping; +using Umbraco.Web.BackOffice.Trees; -namespace Umbraco.Web.Models.Mapping +namespace Umbraco.Web.BackOffice.Mapping { /// /// Declares model mappings for members. diff --git a/src/Umbraco.Web.BackOffice/PropertyEditors/Validation/ContentPropertyValidationResult.cs b/src/Umbraco.Web.BackOffice/PropertyEditors/Validation/ContentPropertyValidationResult.cs index 0f161c5628..f0689c6044 100644 --- a/src/Umbraco.Web.BackOffice/PropertyEditors/Validation/ContentPropertyValidationResult.cs +++ b/src/Umbraco.Web.BackOffice/PropertyEditors/Validation/ContentPropertyValidationResult.cs @@ -1,7 +1,8 @@ using Newtonsoft.Json; using System.ComponentModel.DataAnnotations; +using Umbraco.Web.PropertyEditors.Validation; -namespace Umbraco.Web.PropertyEditors.Validation +namespace Umbraco.Web.BackOffice.PropertyEditors.Validation { /// /// Custom for content properties @@ -9,7 +10,7 @@ namespace Umbraco.Web.PropertyEditors.Validation /// /// This clones the original result and then ensures the nested result if it's the correct type. /// - /// For a more indepth explanation of how server side validation works with the angular app, see this GitHub PR: + /// For a more indepth explanation of how server side validation works with the angular app, see this GitHub PR: /// https://github.com/umbraco/Umbraco-CMS/pull/8339 /// public class ContentPropertyValidationResult : ValidationResult diff --git a/src/Umbraco.Web.BackOffice/PropertyEditors/Validation/ValidationResultConverter.cs b/src/Umbraco.Web.BackOffice/PropertyEditors/Validation/ValidationResultConverter.cs index b5c29bcc35..44f57f9e6c 100644 --- a/src/Umbraco.Web.BackOffice/PropertyEditors/Validation/ValidationResultConverter.cs +++ b/src/Umbraco.Web.BackOffice/PropertyEditors/Validation/ValidationResultConverter.cs @@ -7,8 +7,9 @@ using System.Linq; using Microsoft.AspNetCore.Mvc.ModelBinding; using Umbraco.Core; using Umbraco.Extensions; +using Umbraco.Web.PropertyEditors.Validation; -namespace Umbraco.Web.PropertyEditors.Validation +namespace Umbraco.Web.BackOffice.PropertyEditors.Validation { /// /// Custom json converter for and diff --git a/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs b/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs index 005a0db36e..ca854b6f65 100644 --- a/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs +++ b/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs @@ -41,7 +41,7 @@ namespace Umbraco.Web.BackOffice.Runtime composition.ComposeWebMappingProfiles(); - composition.RegisterUniqueFor(factory => + composition.RegisterUnique(factory => new PhysicalFileSystem( factory.GetInstance(), factory.GetInstance(), @@ -50,6 +50,8 @@ namespace Umbraco.Web.BackOffice.Runtime composition.RegisterUnique(); composition.RegisterUnique(); + + composition.ComposeUmbracoBackOfficeControllers(); } } } diff --git a/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeCookieOptions.cs b/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeCookieOptions.cs index 3b8421ce6a..56c72c3901 100644 --- a/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeCookieOptions.cs +++ b/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeCookieOptions.cs @@ -27,6 +27,7 @@ namespace Umbraco.Web.BackOffice.Security /// public class ConfigureBackOfficeCookieOptions : IConfigureNamedOptions { + private readonly IServiceProvider _serviceProvider; private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly SecuritySettings _securitySettings; private readonly GlobalSettings _globalSettings; @@ -37,10 +38,10 @@ namespace Umbraco.Web.BackOffice.Security private readonly IUserService _userService; private readonly IIpResolver _ipResolver; private readonly ISystemClock _systemClock; - private readonly BackOfficeSessionIdValidator _sessionIdValidator; private readonly LinkGenerator _linkGenerator; public ConfigureBackOfficeCookieOptions( + IServiceProvider serviceProvider, IUmbracoContextAccessor umbracoContextAccessor, IOptions securitySettings, IOptions globalSettings, @@ -51,9 +52,9 @@ namespace Umbraco.Web.BackOffice.Security IUserService userService, IIpResolver ipResolver, ISystemClock systemClock, - BackOfficeSessionIdValidator sessionIdValidator, LinkGenerator linkGenerator) { + _serviceProvider = serviceProvider; _umbracoContextAccessor = umbracoContextAccessor; _securitySettings = securitySettings.Value; _globalSettings = globalSettings.Value; @@ -64,7 +65,6 @@ namespace Umbraco.Web.BackOffice.Security _userService = userService; _ipResolver = ipResolver; _systemClock = systemClock; - _sessionIdValidator = sessionIdValidator; _linkGenerator = linkGenerator; } @@ -226,7 +226,10 @@ namespace Umbraco.Web.BackOffice.Security private async Task EnsureValidSessionId(CookieValidatePrincipalContext context) { if (_runtimeState.Level == RuntimeLevel.Run) - await _sessionIdValidator.ValidateSessionAsync(TimeSpan.FromMinutes(1), context); + { + var validator = _serviceProvider.GetRequiredService(); + await validator.ValidateSessionAsync(TimeSpan.FromMinutes(1), context); + } } /// diff --git a/src/Umbraco.Web.BackOffice/SignalR/IPreviewHub.cs b/src/Umbraco.Web.BackOffice/SignalR/IPreviewHub.cs index 96a28e5c0d..810124010c 100644 --- a/src/Umbraco.Web.BackOffice/SignalR/IPreviewHub.cs +++ b/src/Umbraco.Web.BackOffice/SignalR/IPreviewHub.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using Microsoft.AspNetCore.SignalR; namespace Umbraco.Web.BackOffice.SignalR { diff --git a/src/Umbraco.Web.BackOffice/SignalR/PreviewHub.cs b/src/Umbraco.Web.BackOffice/SignalR/PreviewHub.cs index 794e38b678..e5caea552a 100644 --- a/src/Umbraco.Web.BackOffice/SignalR/PreviewHub.cs +++ b/src/Umbraco.Web.BackOffice/SignalR/PreviewHub.cs @@ -1,5 +1,4 @@ using Microsoft.AspNetCore.SignalR; -using System.Threading.Tasks; namespace Umbraco.Web.BackOffice.SignalR { diff --git a/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComponent.cs b/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComponent.cs index d1f00e9911..ca3d40ccc8 100644 --- a/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComponent.cs +++ b/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComponent.cs @@ -1,5 +1,4 @@ using System; -using System.Configuration; using Microsoft.AspNetCore.SignalR; using Umbraco.Core.Cache; using Umbraco.Core.Composing; diff --git a/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComposer.cs b/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComposer.cs index 6660d918c0..d3c37a729a 100644 --- a/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComposer.cs +++ b/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComposer.cs @@ -1,8 +1,7 @@ using Umbraco.Core; using Umbraco.Core.Composing; -using Umbraco.Web.BackOffice.SignalR; -namespace Umbraco.Web.SignalR +namespace Umbraco.Web.BackOffice.SignalR { [RuntimeLevel(MinLevel = RuntimeLevel.Run)] public class PreviewHubComposer : ComponentComposer, ICoreComposer diff --git a/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs index 6f7eec68f8..c3e3c94b93 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs @@ -1,5 +1,4 @@ - -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Net; @@ -15,16 +14,16 @@ using Umbraco.Core; using Umbraco.Core.Services; using Umbraco.Extensions; using Umbraco.Web.BackOffice.Controllers; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Common.Filters; using Umbraco.Web.Common.ModelBinders; using Umbraco.Web.Models.Trees; using Umbraco.Web.Services; +using Umbraco.Web.Trees; using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { /// /// Used to return tree root nodes diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentBlueprintTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ContentBlueprintTreeController.cs index 607efbf2f9..5477797ccc 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentBlueprintTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentBlueprintTreeController.cs @@ -7,13 +7,13 @@ using Umbraco.Core.Models.Entities; using Umbraco.Core.Services; using Umbraco.Web.Actions; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { /// /// The content blueprint tree controller diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs index 1685b329dd..748c03e5e1 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs @@ -16,15 +16,15 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Security; using Constants = Umbraco.Core.Constants; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Security; using Umbraco.Web.WebApi; using Umbraco.Core.Configuration.Models; using Microsoft.Extensions.Options; +using Umbraco.Web.Trees; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { //We will not allow the tree to render unless the user has access to any of the sections that the tree gets rendered // this is not ideal but until we change permissions to be tree based (not section) there's not much else we can do here. diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs index 227bfd5746..8e678d9673 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs @@ -14,13 +14,13 @@ using Microsoft.AspNetCore.Mvc; using Umbraco.Web.Actions; using Umbraco.Core.Security; using Umbraco.Extensions; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Common.ModelBinders; using Umbraco.Web.Security; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { public abstract class ContentTreeControllerBase : TreeController, ITreeNodeController { diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs index 82e4d70e8c..5c8312c058 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs @@ -7,14 +7,14 @@ using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Web.Actions; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Models.Trees; using Umbraco.Web.Search; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize(Constants.Trees.DocumentTypes)] [Tree(Constants.Applications.Settings, Constants.Trees.DocumentTypes, SortOrder = 0, TreeGroup = Constants.Trees.Groups.Settings)] diff --git a/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs index 7cffe230c7..3502d7a506 100644 --- a/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs @@ -11,11 +11,11 @@ using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Search; using Constants = Umbraco.Core.Constants; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize(Constants.Trees.DataTypes)] [Tree(Constants.Applications.Settings, Constants.Trees.DataTypes, SortOrder = 3, TreeGroup = Constants.Trees.Groups.Settings)] diff --git a/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs index 657772e622..a9878a3dbc 100644 --- a/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs @@ -6,12 +6,12 @@ using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Web.Actions; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize( diff --git a/src/Umbraco.Web.BackOffice/Trees/FilesTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/FilesTreeController.cs index 59fc9739d1..11e2ae8fc7 100644 --- a/src/Umbraco.Web.BackOffice/Trees/FilesTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/FilesTreeController.cs @@ -3,10 +3,10 @@ using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Services; -using Umbraco.Web.BackOffice.Trees; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [Tree(Constants.Applications.Settings, "files", TreeTitle = "Files", TreeUse = TreeUse.Dialog)] [CoreTree] @@ -20,7 +20,7 @@ namespace Umbraco.Web.Trees ILocalizedTextService localizedTextService, UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection, IMenuItemCollectionFactory menuItemCollectionFactory, - IFileSystem fileSystem) + IPhysicalFileSystem fileSystem) : base(localizedTextService, umbracoApiControllerTypeCollection, menuItemCollectionFactory) { FileSystem = fileSystem; diff --git a/src/Umbraco.Web.BackOffice/Trees/ITreeNodeController.cs b/src/Umbraco.Web.BackOffice/Trees/ITreeNodeController.cs index ecdc7b781d..12ff485938 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ITreeNodeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ITreeNodeController.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Umbraco.Web.Common.ModelBinders; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { /// /// Represents an TreeNodeController diff --git a/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs index a3c0354ca9..d4a2c91fad 100644 --- a/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs @@ -1,13 +1,13 @@ using Microsoft.AspNetCore.Http; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize(Constants.Trees.Languages)] [Tree(Constants.Applications.Settings, Constants.Trees.Languages, SortOrder = 11, TreeGroup = Constants.Trees.Groups.Settings)] diff --git a/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs index 4de3670fcd..9ffe6e8b68 100644 --- a/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs @@ -1,13 +1,13 @@ using Microsoft.AspNetCore.Http; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize(Constants.Trees.LogViewer)] [Tree(Constants.Applications.Settings, Constants.Trees.LogViewer, SortOrder= 9, TreeGroup = Constants.Trees.Groups.Settings)] diff --git a/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs index 690b1888c5..567f0a3646 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs @@ -4,12 +4,12 @@ using Umbraco.Core.Services; using Umbraco.Web.Models.Trees; using Umbraco.Web.Actions; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize(Constants.Trees.Macros)] [Tree(Constants.Applications.Settings, Constants.Trees.Macros, TreeTitle = "Macros", SortOrder = 4, TreeGroup = Constants.Trees.Groups.Settings)] diff --git a/src/Umbraco.Web.BackOffice/Trees/MediaTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MediaTreeController.cs index 10edcd46c7..2feedeff80 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MediaTreeController.cs @@ -15,13 +15,13 @@ using Umbraco.Web.Search; using Umbraco.Core.Security; using Constants = Umbraco.Core.Constants; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Security; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { //We will not allow the tree to render unless the user has access to any of the sections that the tree gets rendered // this is not ideal but until we change permissions to be tree based (not section) there's not much else we can do here. diff --git a/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs index 52a66d63ce..4df81b7023 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs @@ -10,11 +10,11 @@ using Umbraco.Web.Actions; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Search; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize(Constants.Trees.MediaTypes)] [Tree(Constants.Applications.Settings, Constants.Trees.MediaTypes, SortOrder = 1, TreeGroup = Constants.Trees.Groups.Settings)] diff --git a/src/Umbraco.Web.BackOffice/Trees/MemberGroupTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MemberGroupTreeController.cs index 22925e27e2..17de4ca37d 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MemberGroupTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MemberGroupTreeController.cs @@ -4,12 +4,12 @@ using Microsoft.AspNetCore.Http; using Umbraco.Core; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize(Constants.Trees.MemberGroups)] [Tree(Constants.Applications.Members, Constants.Trees.MemberGroups, SortOrder = 1)] diff --git a/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs index e6d18f3b72..f38e00d19a 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs @@ -18,9 +18,10 @@ using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Search; using Constants = Umbraco.Core.Constants; using Umbraco.Web.Security; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { //We will not allow the tree to render unless the user has access to any of the sections that the tree gets rendered // this is not ideal but until we change permissions to be tree based (not section) there's not much else we can do here. diff --git a/src/Umbraco.Web.BackOffice/Trees/MemberTypeAndGroupTreeControllerBase.cs b/src/Umbraco.Web.BackOffice/Trees/MemberTypeAndGroupTreeControllerBase.cs index a82d08eeac..d758d8b7f9 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MemberTypeAndGroupTreeControllerBase.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MemberTypeAndGroupTreeControllerBase.cs @@ -3,12 +3,12 @@ using Microsoft.AspNetCore.Http; using Umbraco.Core; using Umbraco.Core.Services; using Umbraco.Web.Actions; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] diff --git a/src/Umbraco.Web.BackOffice/Trees/MemberTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MemberTypeTreeController.cs index ae8a883fda..c9e340617e 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MemberTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MemberTypeTreeController.cs @@ -10,9 +10,10 @@ using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Models.Trees; using Umbraco.Web.Search; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [CoreTree] [UmbracoTreeAuthorize(Constants.Trees.MemberTypes)] diff --git a/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs index 634c093f46..fc1f3d876f 100644 --- a/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs @@ -1,13 +1,13 @@ using Microsoft.AspNetCore.Http; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize(Constants.Trees.Packages)] [Tree(Constants.Applications.Packages, Constants.Trees.Packages, SortOrder = 0, IsSingleNodeTree = true)] diff --git a/src/Umbraco.Web.BackOffice/Trees/PartialViewMacrosTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/PartialViewMacrosTreeController.cs index 7fa4580372..f651c86cae 100644 --- a/src/Umbraco.Web.BackOffice/Trees/PartialViewMacrosTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/PartialViewMacrosTreeController.cs @@ -2,12 +2,12 @@ using Umbraco.Core.IO; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { /// /// Tree for displaying partial view macros in the developer app diff --git a/src/Umbraco.Web.BackOffice/Trees/PartialViewsTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/PartialViewsTreeController.cs index 761475612f..258f77fe17 100644 --- a/src/Umbraco.Web.BackOffice/Trees/PartialViewsTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/PartialViewsTreeController.cs @@ -2,15 +2,14 @@ using Umbraco.Core.IO; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Composing; using Umbraco.Web.Mvc; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -using Umbraco.Web.WebApi.Filters; using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { /// /// Tree for displaying partial views in the settings app diff --git a/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs index a4fffc5760..965e957f02 100644 --- a/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs @@ -6,11 +6,11 @@ using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Web.Actions; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize(Constants.Trees.RelationTypes)] [Tree(Constants.Applications.Settings, Constants.Trees.RelationTypes, SortOrder = 5, TreeGroup = Constants.Trees.Groups.Settings)] diff --git a/src/Umbraco.Web.BackOffice/Trees/ScriptsTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ScriptsTreeController.cs index 8a3b8a1299..4b29c458a1 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ScriptsTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ScriptsTreeController.cs @@ -2,9 +2,10 @@ using Umbraco.Core.IO; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Trees; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [CoreTree] [Tree(Constants.Applications.Settings, Constants.Trees.Scripts, TreeTitle = "Scripts", SortOrder = 10, TreeGroup = Constants.Trees.Groups.Templating)] diff --git a/src/Umbraco.Web.BackOffice/Trees/StylesheetsTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/StylesheetsTreeController.cs index 4e88e60b4e..5b8a9d5298 100644 --- a/src/Umbraco.Web.BackOffice/Trees/StylesheetsTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/StylesheetsTreeController.cs @@ -1,10 +1,10 @@ using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Core.Services; -using Umbraco.Web.BackOffice.Trees; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [CoreTree] [Tree(Constants.Applications.Settings, Constants.Trees.Stylesheets, TreeTitle = "Stylesheets", SortOrder = 9, TreeGroup = Constants.Trees.Groups.Templating)] diff --git a/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs index 109b5c93c9..cfe2d57ce5 100644 --- a/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs @@ -9,15 +9,15 @@ using Umbraco.Core.Services; using Umbraco.Extensions; using Umbraco.Web.Actions; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Models.Trees; using Umbraco.Web.Search; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize(Constants.Trees.Templates)] [Tree(Constants.Applications.Settings, Constants.Trees.Templates, SortOrder = 6, TreeGroup = Constants.Trees.Groups.Templating)] diff --git a/src/Umbraco.Web.BackOffice/Trees/TreeCollectionBuilder.cs b/src/Umbraco.Web.BackOffice/Trees/TreeCollectionBuilder.cs index fb1b642bc8..98438d952b 100644 --- a/src/Umbraco.Web.BackOffice/Trees/TreeCollectionBuilder.cs +++ b/src/Umbraco.Web.BackOffice/Trees/TreeCollectionBuilder.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using Umbraco.Core; using Umbraco.Core.Composing; -using Umbraco.Web.BackOffice.Trees; +using Umbraco.Web.Trees; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { /// /// Builds a . diff --git a/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs index 9019b71d1b..feb8d2a9ec 100644 --- a/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs @@ -7,14 +7,14 @@ using Umbraco.Core.Mapping; using Umbraco.Core.Persistence; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Filters; -using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; using Umbraco.Web.Routing; +using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Trees +namespace Umbraco.Web.BackOffice.Trees { [UmbracoTreeAuthorize(Constants.Trees.Users)] [Tree(Constants.Applications.Users, Constants.Trees.Users, SortOrder = 0, IsSingleNodeTree = true)] diff --git a/src/Umbraco.Web.Common/AspNetCore/UmbracoViewPage.cs b/src/Umbraco.Web.Common/AspNetCore/UmbracoViewPage.cs index fde3d095fe..cf41670d8e 100644 --- a/src/Umbraco.Web.Common/AspNetCore/UmbracoViewPage.cs +++ b/src/Umbraco.Web.Common/AspNetCore/UmbracoViewPage.cs @@ -1,7 +1,10 @@ using System; using System.Text; +using System.Threading.Tasks; using Microsoft.AspNetCore.Http.Extensions; +using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.Razor; +using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Umbraco.Core; @@ -11,6 +14,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Strings; +using Umbraco.Web.Common.ModelBinders; namespace Umbraco.Web.Common.AspNetCore { @@ -29,6 +33,7 @@ namespace Umbraco.Web.Common.AspNetCore private ContentSettings ContentSettings => Context.RequestServices.GetRequiredService>().Value; private IProfilerHtml ProfilerHtml => Context.RequestServices.GetRequiredService(); private IIOHelper IOHelper => Context.RequestServices.GetRequiredService(); + private ContentModelBinder ContentModelBinder => new ContentModelBinder(); protected IUmbracoContext UmbracoContext => _umbracoContext ??= UmbracoContextAccessor.UmbracoContext; @@ -85,5 +90,58 @@ namespace Umbraco.Web.Common.AspNetCore base.WriteLiteral(value); } + + // maps model + protected async Task SetViewDataAsync(ViewDataDictionary viewData) + { + // capture the model before we tinker with the viewData + var viewDataModel = viewData.Model; + + // map the view data (may change its type, may set model to null) + viewData = MapViewDataDictionary(viewData, typeof (TModel)); + + // bind the model + var bindingContext = new DefaultModelBindingContext(); + await ContentModelBinder.BindModelAsync(bindingContext, viewDataModel, typeof (TModel)); + + viewData.Model = bindingContext.Result.Model; + + // set the view data + ViewData = (ViewDataDictionary) viewData; + } + + // viewData is the ViewDataDictionary (maybe ) that we have + // modelType is the type of the model that we need to bind to + // + // figure out whether viewData can accept modelType else replace it + // + private static ViewDataDictionary MapViewDataDictionary(ViewDataDictionary viewData, Type modelType) + { + var viewDataType = viewData.GetType(); + + + if (viewDataType.IsGenericType) + { + // ensure it is the proper generic type + var def = viewDataType.GetGenericTypeDefinition(); + if (def != typeof(ViewDataDictionary<>)) + throw new Exception("Could not map viewData of type \"" + viewDataType.FullName + "\"."); + + // get the viewData model type and compare with the actual view model type: + // viewData is ViewDataDictionary and we will want to assign an + // object of type modelType to the Model property of type viewDataModelType, we + // need to check whether that is possible + var viewDataModelType = viewDataType.GenericTypeArguments[0]; + + if (viewDataModelType.IsAssignableFrom(modelType)) + return viewData; + } + + // if not possible or it is not generic then we need to create a new ViewDataDictionary + var nViewDataType = typeof(ViewDataDictionary<>).MakeGenericType(modelType); + var tViewData = new ViewDataDictionary(viewData) { Model = null }; // temp view data to copy values + var nViewData = (ViewDataDictionary)Activator.CreateInstance(nViewDataType, tViewData); + return nViewData; + } } } diff --git a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs index 2415b4e924..ed0d350dc8 100644 --- a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs @@ -7,7 +7,9 @@ using Smidge; using Smidge.Nuglify; using StackExchange.Profiling; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.Hosting; +using Umbraco.Core.Runtime; using Umbraco.Infrastructure.Logging.Serilog.Enrichers; using Umbraco.Web.Common.Middleware; @@ -40,6 +42,11 @@ namespace Umbraco.Extensions if (!app.UmbracoCanBoot()) return app; var runtime = app.ApplicationServices.GetRequiredService(); + if (runtime is CoreRuntime coreRuntime) + { + coreRuntime.ReplaceFactory(app.ApplicationServices); + } + // Register a listener for application shutdown in order to terminate the runtime var hostLifetime = app.ApplicationServices.GetRequiredService(); var runtimeShutdown = new CoreRuntimeShutdown(runtime, hostLifetime); @@ -48,7 +55,7 @@ namespace Umbraco.Extensions // Register our global threadabort enricher for logging var threadAbortEnricher = app.ApplicationServices.GetRequiredService(); LogContext.Push(threadAbortEnricher); // NOTE: We are not in a using clause because we are not removing it, it is on the global context - + // Start the runtime! runtime.Start(); diff --git a/src/Umbraco.Web.Common/Extensions/CompositionExtensions.cs b/src/Umbraco.Web.Common/Extensions/CompositionExtensions.cs new file mode 100644 index 0000000000..2ce003d226 --- /dev/null +++ b/src/Umbraco.Web.Common/Extensions/CompositionExtensions.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Microsoft.AspNetCore.Mvc; +using Umbraco.Core.Composing; +using Umbraco.Web.Common.Controllers; +using Umbraco.Web.Mvc; + +namespace Umbraco.Extensions +{ + public static class CompositionExtensions + { + public static void RegisterControllers(this Composition composition, IEnumerable controllerTypes) + { + foreach (var controllerType in controllerTypes) + composition.Register(controllerType, Lifetime.Request); + } + } +} diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs index f91fdceb4f..ebe792a8a1 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs @@ -26,6 +26,7 @@ using Umbraco.Core.Logging.Serilog; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Runtime; +using Umbraco.Infrastructure.Composing; using Umbraco.Web.Common.AspNetCore; using Umbraco.Web.Common.Profiler; using ConnectionStrings = Umbraco.Core.Configuration.Models.ConnectionStrings; @@ -181,10 +182,6 @@ namespace Umbraco.Extensions /// public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment, IConfiguration configuration, out IFactory factory) { - if (!UmbracoServiceProviderFactory.IsActive) - throw new InvalidOperationException("Ensure to add UseUmbraco() in your Program.cs after ConfigureWebHostDefaults to enable Umbraco's service provider factory"); - - var umbContainer = UmbracoServiceProviderFactory.UmbracoContainer; var loggingConfig = new LoggingConfiguration( Path.Combine(webHostEnvironment.ContentRootPath, "umbraco", "logs")); @@ -199,8 +196,15 @@ namespace Umbraco.Extensions requestCache, new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache()))); + /* TODO: MSDI - Post initial merge we can clean up a lot. + * Change the method signatures lower down + * Or even just remove IRegister / IFactory interfaces entirely. + * If we try to do it immediately, merging becomes a nightmare. + */ + var register = new ServiceCollectionRegistryAdapter(services); + services.AddUmbracoCore(webHostEnvironment, - umbContainer, + register, Assembly.GetEntryAssembly(), appCaches, loggingConfig, diff --git a/src/Umbraco.Web.Common/ModelBinders/ContentModelBinder.cs b/src/Umbraco.Web.Common/ModelBinders/ContentModelBinder.cs index 43d9df4586..113f411c6f 100644 --- a/src/Umbraco.Web.Common/ModelBinders/ContentModelBinder.cs +++ b/src/Umbraco.Web.Common/ModelBinders/ContentModelBinder.cs @@ -27,7 +27,7 @@ namespace Umbraco.Web.Common.ModelBinders // No need for type checks to ensure we have the appropriate binder, as in .NET Core this is handled in the provider, // in this case ContentModelBinderProvider. - // Being defensice though.... if for any reason the model is not either IContentModel or IPublishedContent, + // Being defensive though.... if for any reason the model is not either IContentModel or IPublishedContent, // then we return since those are the only types this binder is dealing with. if (source is IContentModel == false && source is IPublishedContent == false) { @@ -36,7 +36,7 @@ namespace Umbraco.Web.Common.ModelBinders BindModelAsync(bindingContext, source, bindingContext.ModelType); return Task.CompletedTask; - } + } // source is the model that we have // modelType is the type of the model that we need to bind to @@ -56,8 +56,9 @@ namespace Umbraco.Web.Common.ModelBinders // If types already match, return var sourceType = source.GetType(); - if (sourceType.Inherits(modelType)) // includes == + if (sourceType. Inherits(modelType)) // includes == { + bindingContext.Result = ModelBindingResult.Success(source); return Task.CompletedTask; } diff --git a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs index 0d91892445..8f890c4259 100644 --- a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs +++ b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs @@ -72,7 +72,6 @@ namespace Umbraco.Web.Common.Runtime composition.RegisterUnique(); composition.RegisterUnique(); - composition.RegisterUnique(); // register the umbraco context factory composition.RegisterUnique(); diff --git a/src/Umbraco.Web.UI.NetCore/Program.cs b/src/Umbraco.Web.UI.NetCore/Program.cs index 4a7722597d..4f87e74075 100644 --- a/src/Umbraco.Web.UI.NetCore/Program.cs +++ b/src/Umbraco.Web.UI.NetCore/Program.cs @@ -21,6 +21,10 @@ namespace Umbraco.Web.UI.NetCore x.ClearProviders(); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }) + // TODO: MSDI - this should probably be on one day, more so when we can reduce the number + // of times we build a ServiceProvider from services collection + // right now it's just painful. + .UseDefaultServiceProvider(options => options.ValidateOnBuild = false) .UseUmbraco(); } } diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index aa141b2624..b4ef7f59ec 100644 --- a/src/Umbraco.Web.UI.NetCore/Startup.cs +++ b/src/Umbraco.Web.UI.NetCore/Startup.cs @@ -33,7 +33,10 @@ namespace Umbraco.Web.UI.NetCore public void ConfigureServices(IServiceCollection services) { var umbracoBuilder = services.AddUmbraco(_env, _config); - umbracoBuilder.BuildWithAllBackOfficeComponents(); + umbracoBuilder + .WithAllBackOfficeComponents() + .WithAllWebsiteComponents() + .Build(); } diff --git a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/cs.xml b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/cs.xml index 914ac366cd..739b8d4684 100644 --- a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/cs.xml +++ b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/cs.xml @@ -2029,7 +2029,6 @@ Try Skip IIS Custom Errors je aktuálně nastaveno na '%0%'. Doporučuje se nastavit %1% pro vaši verzi služby IIS (%2%). Try Skip IIS Custom Errors úspěšně nastaveno na '%0%'. - Soubor neexistuje: '%0%'. '% 0%' v konfiguračním souboru '% 1%'.]]> Došlo k chybě, zkontrolujte ji v logu: %0%. Databáze - Databázové schéma je pro tuto verzi Umbraco správné @@ -2059,6 +2058,10 @@ Režim sledování je aktuálně povolen. Před spuštěním se doporučuje toto nastavení deaktivovat. Režim sledování byl úspěšně deaktivován. Všechny složky mají nastavena správná oprávnění. + + Soubor neexistuje: '%0%'. diff --git a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/de.xml b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/de.xml index 86b1d6c130..cb95283bb7 100644 --- a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/de.xml +++ b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/de.xml @@ -2101,7 +2101,6 @@ "trySkipIisCustomErrors" ist auf '%0%' gestellt und Sie verwenden IIS-Version '%1%'. "trySkipIisCustomErrors" ist aktuell auf '%0%' gestellt. Für Ihre IIS-Version (%2%) wird empfohlen, diese auf '%1%' zu stellen. "trySkipIisCustomErrors" wurde erfolgreich auf '%0%' gestellt. - Folgende Datei ist nicht vorhanden: '%0%'. '%0%' wurde nicht in der Konfigurationsdatei '%1%' gefunden.]]> Es trat ein Fehler auf, für eine vollständige Fehlermeldung suchen Sie in den Logs nach: %0% Datenbank - Das Datenbank-Schema ist korrekt für diese Umbraco-Version @@ -2130,6 +2129,10 @@ Trace-Modus ist gegenwertig eingeschaltet. Es ist empfehlenswert diesen vor Live-Gang abzuschalten. Trace-Modus wurde erfolgreich abgeschaltet. Alle Ordner haben die korrekten Zugriffsrechte. + + Folgende Datei ist nicht vorhanden: '%0%'. %0%.]]> %0%. Falls nicht in diese geschrieben wird, brauchen Sie nichts zu unternehmen.]]> Alle Dateien haben die korrekten Zugriffsrechte. diff --git a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml index 6b1fa7e420..0d1188db50 100644 --- a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml @@ -2095,7 +2095,6 @@ To manage your website, simply open the Umbraco back office and start adding con Try Skip IIS Custom Errors is currently '%0%'. It is recommended to set this to '%1%' for your IIS version (%2%). Try Skip IIS Custom Errors successfully set to '%0%'. - File does not exist: '%0%'. '%0%' in config file '%1%'.]]> There was an error, check log for full error: %0%. Database - The database schema is correct for this version of Umbraco @@ -2125,6 +2124,10 @@ To manage your website, simply open the Umbraco back office and start adding con Trace mode is currently enabled. It is recommended to disable this setting before go live. Trace mode successfully disabled. All folders have the correct permissions set. + + File does not exist: '%0%'. diff --git a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml index c45049087d..0599caee9c 100644 --- a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml @@ -2116,7 +2116,6 @@ To manage your website, simply open the Umbraco back office and start adding con Try Skip IIS Custom Errors is currently '%0%'. It is recommended to set this to '%1%' for your IIS version (%2%). Try Skip IIS Custom Errors successfully set to '%0%'. - File does not exist: '%0%'. '%0%' in config file '%1%'.]]> There was an error, check log for full error: %0%. Database - The database schema is correct for this version of Umbraco @@ -2152,6 +2151,10 @@ To manage your website, simply open the Umbraco back office and start adding con %0%.]]> %0%. If they aren't being written to no action need be taken.]]> All files have the correct permissions set. + + File does not exist: '%0%'. diff --git a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/es.xml b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/es.xml index c35c84ebdc..678afa10d6 100644 --- a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/es.xml +++ b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/es.xml @@ -1568,8 +1568,6 @@ Intentar saltar Errores Personalizados de IIS está '%0%'. Se recomienda configurarlo como '%1%' para tu versión (%2%) de IIS. Intentar saltar Errores Personalizados de IIS se configuró como con '%0%' éxito. - Archivo no existe: '%0%'. - '%0%' en archivo de configuración '%1%'.]]> Hubo un error, revisa los logs para ver el error completo: %0%. El certificado de tu sitio es válido. Error validando certificado: '%0%' @@ -1601,6 +1599,10 @@ %0%.]]> %0%. Opcional.]]> Todos los archivos tienen los permisos correspondientes. + + '%0%' en archivo de configuración '%1%'.]]> diff --git a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/fr.xml b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/fr.xml index b83ee4f9fe..17875e53e4 100644 --- a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/fr.xml +++ b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/fr.xml @@ -2040,7 +2040,6 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à Try Skip IIS Custom Errors est actuellement fixé à '%0%'. Il est recommandé de fixer la valeur à '%1%' pour votre version IIS (%2%). Try Skip IIS Custom Errors a été rectifié avec succès à la valeur '%0%'. - Le fichier n'existe pas : '%0%'. '%0%' dans le fichier config '%1%'.]]> Une erreur est survenue, consultez le log pour voir l'erreur complète : %0%. Base de données - Le schéma de la base de données est correct pour cette version de Umbraco @@ -2070,6 +2069,10 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à Le mode tracing est actuellement activé. Il est recommandé de désactiver cette configuration avant la mise en ligne. Le mode tracing a été désactivé avec succès. Tous les répertoires ont les configurations de permissions adéquates. + + Le fichier n'existe pas : '%0%'. @@ -2355,4 +2358,4 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à ]]> - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/nl.xml b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/nl.xml index 8361383b58..27894b4a1d 100644 --- a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/nl.xml +++ b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/nl.xml @@ -1326,7 +1326,6 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Try Skip IIS Custom foutmeldingen is ingesteld op '%0%'. Het wordt voor de gebruikte IIS versie (%2%) aangeraden deze in te stellen op '%1%'. Try Skip IIS Custom foutmeldingen ingesteld op '%0%'. - Het volgende bestand bestaat niet: '%0%'. '%0%' kon niet gevonden worden in configuratie bestand '%1%'.]]> Er is een fout opgetreden. Bekijk de log file voor de volledige fout: %0%. Het cerficaat van de website is ongeldig. @@ -1357,6 +1356,10 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je %0%.]]> %0%. Als deze niet in gebruik zijn voor deze omgeving hoeft er geen actie te worden ondernomen.]]> All files have the correct permissions set. + + Het volgende bestand bestaat niet: '%0%'. diff --git a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/pl.xml b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/pl.xml index fd806041c5..1c095448b5 100644 --- a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/pl.xml +++ b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/pl.xml @@ -1403,7 +1403,6 @@ Naciśnij przycisk instaluj, aby zainstalować bazę danych Umb Try Skip IIS Custom Errors wynosi obecnie '%0%'. Zalecane jest ustawienie go na '%1%' dla Twojego IIS w wersji (%2%). Try Skip IIS Custom Errors ustawiono z powodzeniem na '%0%'. - Plik nie istnieje: '%0%'. '%0%' w pliku konfiguracyjnym '%1%'.]]> Wystąpił błąd, sprawdź logi, aby wyświetlić pełen opis błędu: %0%. Certifikat Twojej strony jest poprawny. @@ -1436,6 +1435,7 @@ Naciśnij przycisk instaluj, aby zainstalować bazę danych Umb %0%.]]> %0%. Jeśli nie będzie nic w nich pisane, żadne działania nie muszą być podejmowane.]]> Wszystkie pliki mają ustawione poprawne uprawnienia. + Plik nie istnieje: '%0%'. diff --git a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/ru.xml b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/ru.xml index 7a3e099262..6654543ec8 100644 --- a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/ru.xml +++ b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/ru.xml @@ -694,7 +694,6 @@ Параметр 'Try Skip IIS Custom Errors' сейчас установлен в '%0%'. Рекомендуется установить в '%1%' для Вашего текущего IIS версии (%2%). Параметр 'Try Skip IIS Custom Errors' успешно установлен в '%0%'. - Файл не существует: '%0%'. '%0%' в файле конфигурации '%1%'.]]> Обнаружена ошибка, для получения полной информации обратитесь к журналу: %0%. Ошибка проверки адреса URL %0% - '%1%' @@ -725,6 +724,10 @@ %0%.]]> %0%. Если в них не разрешена запись, не нужно предпринимать никаких действий.]]> Все файлы имеют корректно установленные параметры безопасности. + + Файл не существует: '%0%'. diff --git a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/zh.xml b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/zh.xml index 5210b46bcc..5a470583a8 100644 --- a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/zh.xml +++ b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/zh.xml @@ -1190,7 +1190,6 @@ Try Skip IIS Custom Errors is currently '%0%'. It is recommended to set this to '%1%' for your IIS version (%2%). Try Skip IIS Custom Errors successfully set to '%0%'. - File does not exist: '%0%'. '%0%' in config file '%1%'.]]> There was an error, check log for full error: %0%. Your site certificate was marked as valid. @@ -1221,6 +1220,10 @@ %0%.]]> %0%. If they aren't being written to no action need be taken.]]> All files have the correct permissions set. + + File does not exist: '%0%'. diff --git a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/zh_tw.xml b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/zh_tw.xml index 320c3f63d8..06e8ec3e54 100644 --- a/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/zh_tw.xml +++ b/src/Umbraco.Web.UI.NetCore/umbraco/config/lang/zh_tw.xml @@ -1170,7 +1170,6 @@ 嘗試略過IIS自訂錯誤目前設為 %0%,然而在您使用的IIS版本為 %2% 時,建議設定是 %1%。 嘗試略過IIS自訂錯誤已成功設為 %0%。 - 檔案不存在:%0%。 '%1%'中無法找到'%0%'。]]> 有錯誤產生,請參閱下列錯誤的紀錄:%0%。 憑證驗證錯誤:%0% @@ -1200,6 +1199,10 @@ %0%。]]> %0%。如果無須寫入,不需採取行動。]]> 所有檔案已有正確權限設定。 + + 檔案不存在:%0%。 diff --git a/src/Umbraco.Web.Website/Extensions/CompositionExtensions.cs b/src/Umbraco.Web.Website/Extensions/CompositionExtensions.cs new file mode 100644 index 0000000000..c832f2fac0 --- /dev/null +++ b/src/Umbraco.Web.Website/Extensions/CompositionExtensions.cs @@ -0,0 +1,39 @@ +using System.Linq; +using Umbraco.Core.Composing; +using Umbraco.Web.Common.Controllers; +using Umbraco.Web.Mvc; +using Umbraco.Web.Website.Controllers; + +namespace Umbraco.Extensions +{ + public static class CompositionExtensions + { + /// + /// Registers Umbraco website controllers. + /// + public static Composition ComposeWebsiteUmbracoControllers(this Composition composition) + { + composition.RegisterControllers(new [] + { + // typeof(UmbProfileController), //TODO introduce when migrated + // typeof(UmbLoginStatusController),//TODO introduce when migrated + // typeof(UmbRegisterController),//TODO introduce when migrated + // typeof(UmbLoginController),//TODO introduce when migrated + typeof(RenderMvcController), + + }); + + var umbracoWebAssembly = typeof(SurfaceController).Assembly; + + // scan and register every PluginController in everything (PluginController is IDiscoverable and IController) + var nonUmbracoWebPluginController = composition.TypeLoader.GetTypes().Where(x => x.Assembly != umbracoWebAssembly); + composition.RegisterControllers(nonUmbracoWebPluginController); + + // can and register every IRenderMvcController in everything (IRenderMvcController is IDiscoverable) + var renderMvcControllers = composition.TypeLoader.GetTypes().Where(x => x.Assembly != umbracoWebAssembly); + composition.RegisterControllers(renderMvcControllers); + + return composition; + } + } +} diff --git a/src/Umbraco.Web.Website/Extensions/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.Website/Extensions/UmbracoBuilderExtensions.cs new file mode 100644 index 0000000000..8e56cd6dca --- /dev/null +++ b/src/Umbraco.Web.Website/Extensions/UmbracoBuilderExtensions.cs @@ -0,0 +1,20 @@ +using Umbraco.Web.Common.Builder; + +namespace Umbraco.Extensions +{ + public static class UmbracoBuilderExtensions + { + public static IUmbracoBuilder WithAllWebsiteComponents(this IUmbracoBuilder builder) + { + builder + .WithUmbracoWebsite(); + + return builder; + } + + public static IUmbracoBuilder WithUmbracoWebsite(this IUmbracoBuilder builder) + => builder.AddWith(nameof(WithUmbracoWebsite), () => builder.Services.AddUmbracoWebsite()); + + + } +} diff --git a/src/Umbraco.Web.Website/Extensions/UmbracoWebstiteServiceCollectionExtensions.cs b/src/Umbraco.Web.Website/Extensions/UmbracoWebstiteServiceCollectionExtensions.cs new file mode 100644 index 0000000000..bdc9ee840c --- /dev/null +++ b/src/Umbraco.Web.Website/Extensions/UmbracoWebstiteServiceCollectionExtensions.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.Extensions.DependencyInjection; + +namespace Umbraco.Extensions +{ + public static class UmbracoWebstiteServiceCollectionExtensions + { + public static void AddUmbracoWebsite(this IServiceCollection services) + { + services.AddSingleton(); + } + } +} diff --git a/src/Umbraco.Web.Website/Runtime/WebsiteComposer.cs b/src/Umbraco.Web.Website/Runtime/WebsiteComposer.cs new file mode 100644 index 0000000000..0e99875dc0 --- /dev/null +++ b/src/Umbraco.Web.Website/Runtime/WebsiteComposer.cs @@ -0,0 +1,24 @@ +using Umbraco.Core.Composing; +using Umbraco.Extensions; +using Umbraco.Web.Common.Runtime; +using Umbraco.Web.Website.Controllers; + +namespace Umbraco.Web.Website.Runtime +{ + // web's initial composer composes after core's, and before all core composers + [ComposeBefore(typeof(ICoreComposer))] + [ComposeAfter(typeof(AspNetCoreComposer))] + public class WebsiteComposer : IComposer + { + public void Compose(Composition composition) + { + + composition + .ComposeWebsiteUmbracoControllers() + //.SetDefaultRenderMvcController()// default controller for template views + ; + + } + } +} + diff --git a/src/Umbraco.Web/Composing/CompositionExtensions/Controllers.cs b/src/Umbraco.Web/Composing/CompositionExtensions/Controllers.cs deleted file mode 100644 index 329c93360b..0000000000 --- a/src/Umbraco.Web/Composing/CompositionExtensions/Controllers.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Web.Http.Controllers; -using System.Web.Mvc; -using Umbraco.Core.Composing; -using Umbraco.Web.Mvc; -using Umbraco.Web.WebApi; - -namespace Umbraco.Web.Composing.CompositionExtensions -{ - internal static class Controllers - { - /// - /// Registers Umbraco controllers. - /// - public static Composition ComposeUmbracoControllers(this Composition composition, Assembly umbracoWebAssembly) - { - // notes - // - // We scan and auto-registers: - // - every IController and IHttpController that *we* have in Umbraco.Web - // - PluginController, RenderMvcController and UmbracoApiController in every assembly - // - // We do NOT scan: - // - any IController or IHttpController (anything not PluginController nor UmbracoApiController), outside of Umbraco.Web - // which means that users HAVE to explicitly register their own non-Umbraco controllers - // - // This is because we try to achieve a balance between "simple" and "fast. Scanning for PluginController or - // UmbracoApiController is fast-ish because they both are IDiscoverable. Scanning for IController or IHttpController - // is a full, non-cached scan = expensive, we do it only for 1 assembly. - // - // TODO: find a way to scan for IController *and* IHttpController in one single pass - // or, actually register them manually so don't require a full scan for these - // 5 are IController but not PluginController - // Umbraco.Web.Mvc.RenderMvcController - // Umbraco.Web.Install.Controllers.InstallController - // Umbraco.Web.Macros.PartialViewMacroController - // Umbraco.Web.Editors.PreviewController - // Umbraco.Web.Editors.BackOfficeController - // 9 are IHttpController but not UmbracoApiController - // Umbraco.Web.Controllers.UmbProfileController - // Umbraco.Web.Controllers.UmbLoginStatusController - // Umbraco.Web.Controllers.UmbRegisterController - // Umbraco.Web.Controllers.UmbLoginController - // Umbraco.Web.Mvc.RenderMvcController - // Umbraco.Web.Install.Controllers.InstallController - // Umbraco.Web.Macros.PartialViewMacroController - // Umbraco.Web.Editors.PreviewController - // Umbraco.Web.Editors.BackOfficeController - - // scan and register every IController in Umbraco.Web - var umbracoWebControllers = composition.TypeLoader.GetTypes(specificAssemblies: new[] { umbracoWebAssembly }); - //foreach (var controller in umbracoWebControllers.Where(x => !typeof(PluginController).IsAssignableFrom(x))) - // Current.Logger.Debug(typeof(LightInjectExtensions), "IController NOT PluginController: " + controller.FullName); - composition.RegisterControllers(umbracoWebControllers); - - // scan and register every PluginController in everything (PluginController is IDiscoverable and IController) - var nonUmbracoWebPluginController = composition.TypeLoader.GetTypes().Where(x => x.Assembly != umbracoWebAssembly); - composition.RegisterControllers(nonUmbracoWebPluginController); - - // can and register every IRenderMvcController in everything (IRenderMvcController is IDiscoverable) - var renderMvcControllers = composition.TypeLoader.GetTypes().Where(x => x.Assembly != umbracoWebAssembly); - composition.RegisterControllers(renderMvcControllers); - - // scan and register every IHttpController in Umbraco.Web - var umbracoWebHttpControllers = composition.TypeLoader.GetTypes(specificAssemblies: new[] { umbracoWebAssembly }); - //foreach (var controller in umbracoWebControllers.Where(x => !typeof(UmbracoApiController).IsAssignableFrom(x))) - // Current.Logger.Debug(typeof(LightInjectExtensions), "IHttpController NOT UmbracoApiController: " + controller.FullName); - composition.RegisterControllers(umbracoWebHttpControllers); - - // scan and register every UmbracoApiController in everything (UmbracoApiController is IDiscoverable and IHttpController) - var nonUmbracoWebApiControllers = composition.TypeLoader.GetTypes().Where(x => x.Assembly != umbracoWebAssembly); - composition.RegisterControllers(nonUmbracoWebApiControllers); - - return composition; - } - - private static void RegisterControllers(this Composition composition, IEnumerable controllerTypes) - { - foreach (var controllerType in controllerTypes) - composition.Register(controllerType, Lifetime.Request); - } - } -} diff --git a/src/Umbraco.Web/Composing/Current.cs b/src/Umbraco.Web/Composing/Current.cs index 44468f2943..5a190a90a5 100644 --- a/src/Umbraco.Web/Composing/Current.cs +++ b/src/Umbraco.Web/Composing/Current.cs @@ -10,6 +10,7 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Persistence; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.HealthCheck; using Umbraco.Core.Hosting; using Umbraco.Core.Mapping; using Umbraco.Core.Templates; @@ -166,9 +167,6 @@ namespace Umbraco.Web.Composing internal static SurfaceControllerTypeCollection SurfaceControllerTypes => Factory.GetInstance(); - public static FilteredControllerFactoryCollection FilteredControllerFactories - => Factory.GetInstance(); - internal static IPublishedSnapshotService PublishedSnapshotService => Factory.GetInstance(); @@ -215,38 +213,12 @@ namespace Umbraco.Web.Composing public static IRuntimeState RuntimeState => Factory.GetInstance(); - public static TypeLoader TypeLoader => Factory.GetInstance(); - - public static UrlSegmentProviderCollection UrlSegmentProviders => Factory.GetInstance(); - public static CacheRefresherCollection CacheRefreshers => Factory.GetInstance(); - public static DataEditorCollection DataEditors => Factory.GetInstance(); - - public static DataValueReferenceFactoryCollection DataValueReferenceFactories => Factory.GetInstance(); - - public static PropertyEditorCollection PropertyEditors => Factory.GetInstance(); - - public static ParameterEditorCollection ParameterEditors => Factory.GetInstance(); - - internal static ManifestValueValidatorCollection ManifestValidators => Factory.GetInstance(); - - internal static IPackageActionRunner PackageActionRunner => Factory.GetInstance(); - - internal static PackageActionCollection PackageActions => Factory.GetInstance(); - - internal static PropertyValueConverterCollection PropertyValueConverters => Factory.GetInstance(); - internal static IPublishedModelFactory PublishedModelFactory => Factory.GetInstance(); public static IServerMessenger ServerMessenger => Factory.GetInstance(); - public static IServerRegistrar ServerRegistrar => Factory.GetInstance(); - - public static ICultureDictionaryFactory CultureDictionaryFactory => Factory.GetInstance(); - - public static IShortStringHelper ShortStringHelper => Factory.GetInstance(); - public static ILogger Logger => Factory.GetInstance>(); public static ILoggerFactory LoggerFactory => Factory.GetInstance(); @@ -263,10 +235,6 @@ namespace Umbraco.Web.Composing public static IScopeProvider ScopeProvider => Factory.GetInstance(); - public static IFileSystems FileSystems => Factory.GetInstance(); - - public static ISqlContext SqlContext => Factory.GetInstance(); - public static IPublishedContentTypeFactory PublishedContentTypeFactory => Factory.GetInstance(); public static IPublishedValueFallback PublishedValueFallback => Factory.GetInstance(); diff --git a/src/Umbraco.Web/CompositionExtensions.cs b/src/Umbraco.Web/CompositionExtensions.cs index 85b7b68c35..906c8fb60d 100644 --- a/src/Umbraco.Web/CompositionExtensions.cs +++ b/src/Umbraco.Web/CompositionExtensions.cs @@ -28,21 +28,8 @@ namespace Umbraco.Web /// public static class WebCompositionExtensions { - #region Collection Builders - /// - /// Gets the filtered controller factories collection builder. - /// - /// The composition. - /// - public static FilteredControllerFactoryCollectionBuilder FilteredControllerFactory(this Composition composition) - => composition.WithCollectionBuilder(); - - - - #endregion - #region Uniques /// diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs index 5265dc13cb..1ca85d919d 100644 --- a/src/Umbraco.Web/Editors/AuthenticationController.cs +++ b/src/Umbraco.Web/Editors/AuthenticationController.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Net; using System.Net.Http; using System.Collections.Generic; -using System.Net.Mail; using System.Security.Principal; using System.Threading.Tasks; using System.Web; diff --git a/src/Umbraco.Web/Logging/WebProfiler.cs b/src/Umbraco.Web/Logging/WebProfiler.cs deleted file mode 100755 index 6f15be7ecd..0000000000 --- a/src/Umbraco.Web/Logging/WebProfiler.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.Threading; -using System.Web; -using StackExchange.Profiling; -using StackExchange.Profiling.SqlFormatters; -using Umbraco.Core; -using Umbraco.Core.Logging; - -namespace Umbraco.Web.Logging -{ - /// - /// Implements by using the MiniProfiler framework. - /// - /// - /// Profiling only runs when the app is in debug mode, see WebRuntime for how this gets created - /// - internal class WebProfiler : IProfiler, IProfilerHtml - { - private const string BootRequestItemKey = "Umbraco.Core.Logging.WebProfiler__isBootRequest"; - private readonly WebProfilerProvider _provider; - private int _first; - - public WebProfiler() - { - // create our own provider, which can provide a profiler even during boot - _provider = new WebProfilerProvider(); - - //see https://miniprofiler.com/dotnet/AspDotNet - MiniProfiler.Configure(new MiniProfilerOptions - { - SqlFormatter = new SqlServerFormatter(), - StackMaxLength = 5000, - ProfilerProvider = _provider - }); - } - - public void UmbracoApplicationBeginRequest(object sender, EventArgs e) - { - // if this is the first request, notify our own provider that this request is the boot request - var first = Interlocked.Exchange(ref _first, 1) == 0; - if (first) - { - _provider.BeginBootRequest(); - ((HttpApplication) sender).Context.Items[BootRequestItemKey] = true; - // and no need to start anything, profiler is already there - } - // else start a profiler, the normal way - else if (ShouldProfile(sender)) - Start(); - } - - public void UmbracoApplicationEndRequest(object sender, EventArgs e) - { - // if this is the boot request, or if we should profile this request, stop - // (the boot request is always profiled, no matter what) - var isBootRequest = ((HttpApplication) sender).Context.Items[BootRequestItemKey] != null; - if (isBootRequest) - _provider.EndBootRequest(); - if (isBootRequest || ShouldProfile(sender)) - Stop(); - } - - private static bool ShouldProfile(object sender) - { - var request = TryGetRequest(sender); - if (request.Success == false) return false; - - if (request.Result.Url.IsClientSideRequest()) return false; - if (bool.TryParse(request.Result.QueryString["umbDebug"], out var umbDebug)) return umbDebug; - if (bool.TryParse(request.Result.Headers["X-UMB-DEBUG"], out var xUmbDebug)) return xUmbDebug; - if (bool.TryParse(request.Result.Cookies["UMB-DEBUG"]?.Value, out var cUmbDebug)) return cUmbDebug; - return false; - } - - /// - public string Render() - { - return MiniProfiler.Current.RenderIncludes(RenderPosition.Right).ToString(); - } - - /// - public IDisposable Step(string name) - { - return MiniProfiler.Current?.Step(name); - } - - /// - public void Start() - { - MiniProfiler.StartNew(); - } - - /// - public void Stop(bool discardResults = false) - { - MiniProfiler.Current?.Stop(discardResults); - } - - private static Attempt TryGetRequest(object sender) - { - if (sender is HttpRequest httpRequest) - return Attempt.Succeed(new HttpRequestWrapper(httpRequest)); - - var app = sender as HttpApplication; - if (app == null) return Attempt.Fail(); - - try - { - var req = app.Request; - return Attempt.Succeed(new HttpRequestWrapper(req)); - } - catch (HttpException ex) - { - return Attempt.Fail(ex); - } - } - } -} diff --git a/src/Umbraco.Web/Logging/WebProfilerComponent.cs b/src/Umbraco.Web/Logging/WebProfilerComponent.cs deleted file mode 100755 index f2ac5e532c..0000000000 --- a/src/Umbraco.Web/Logging/WebProfilerComponent.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web; -using Microsoft.Extensions.Logging; -using Umbraco.Core.Composing; -using Umbraco.Core.Logging; - -namespace Umbraco.Web.Logging -{ - internal sealed class WebProfilerComponent : IComponent - { - private readonly WebProfiler _profiler; - private readonly bool _profile; - - public WebProfilerComponent(IProfiler profiler, ILogger logger) - { - _profile = true; - - // although registered in WebRuntime.Compose, ensure that we have not - // been replaced by another component, and we are still "the" profiler - _profiler = profiler as WebProfiler; - if (_profiler != null) return; - - // if VoidProfiler was registered, let it be known - if (profiler is VoidProfiler) - logger.LogInformation("Profiler is VoidProfiler, not profiling (must run debug mode to profile)."); - _profile = false; - } - - public void Initialize() - { - if (!_profile) return; - - // bind to ApplicationInit - ie execute the application initialization for *each* application - // it would be a mistake to try and bind to the current application events - UmbracoApplicationBase.ApplicationInit += InitializeApplication; - } - - public void Terminate() - { - UmbracoApplicationBase.ApplicationInit -= InitializeApplication; - } - - private void InitializeApplication(object sender, EventArgs args) - { - if (!(sender is HttpApplication app)) return; - - // NOTE: We do not unbind these events ... because you just can't do that for HttpApplication events, they will - // be removed when the app dies. - app.BeginRequest += BeginRequest; - app.EndRequest += EndRequest; - } - - private void BeginRequest(object s, EventArgs a) => _profiler.UmbracoApplicationBeginRequest(s, a); - - private void EndRequest(object s, EventArgs a) => _profiler.UmbracoApplicationEndRequest(s, a); - } -} diff --git a/src/Umbraco.Web/Logging/WebProfilerComposer.cs b/src/Umbraco.Web/Logging/WebProfilerComposer.cs deleted file mode 100644 index 283c519b44..0000000000 --- a/src/Umbraco.Web/Logging/WebProfilerComposer.cs +++ /dev/null @@ -1,7 +0,0 @@ - using Umbraco.Core.Composing; - -namespace Umbraco.Web.Logging -{ - internal class WebProfilerComposer : ComponentComposer, ICoreComposer - { } -} diff --git a/src/Umbraco.Web/Logging/WebProfilerProvider.cs b/src/Umbraco.Web/Logging/WebProfilerProvider.cs deleted file mode 100755 index dbb81cf232..0000000000 --- a/src/Umbraco.Web/Logging/WebProfilerProvider.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System; -using System.Threading; -using System.Web; -using StackExchange.Profiling; -using StackExchange.Profiling.Internal; - -namespace Umbraco.Web.Logging -{ - /// - /// This is a custom MiniProfiler WebRequestProfilerProvider (which is generally the default) that allows - /// us to profile items during app startup - before an HttpRequest is created - /// - /// - /// Once the boot phase is changed to BootPhase.BootRequest then the base class (default) provider will handle all - /// profiling data and this sub class no longer performs any logic. - /// - internal class WebProfilerProvider : AspNetRequestProvider - { - private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(); - private MiniProfiler _startupProfiler; - private int _first; - private volatile BootPhase _bootPhase; - - public WebProfilerProvider() - { - // booting... - _bootPhase = BootPhase.Boot; - } - - /// - /// Indicates the boot phase. - /// - private enum BootPhase - { - Boot = 0, // boot phase (before the 1st request even begins) - BootRequest = 1, // request boot phase (during the 1st request) - Booted = 2 // done booting - } - - public void BeginBootRequest() - { - _locker.EnterWriteLock(); - try - { - if (_bootPhase != BootPhase.Boot) - throw new InvalidOperationException("Invalid boot phase."); - _bootPhase = BootPhase.BootRequest; - - // assign the profiler to be the current MiniProfiler for the request - // is's already active, starting and all - HttpContext.Current.Items[":mini-profiler:"] = _startupProfiler; - } - finally - { - _locker.ExitWriteLock(); - } - } - - public void EndBootRequest() - { - _locker.EnterWriteLock(); - try - { - if (_bootPhase != BootPhase.BootRequest) - throw new InvalidOperationException("Invalid boot phase."); - _bootPhase = BootPhase.Booted; - - _startupProfiler = null; - } - finally - { - _locker.ExitWriteLock(); - } - } - - /// - /// Starts a new MiniProfiler. - /// - /// - /// This is called when WebProfiler calls MiniProfiler.Start() so, - /// - as a result of WebRuntime starting the WebProfiler, and - /// - assuming profiling is enabled, on every BeginRequest that should be profiled, - /// - except for the very first one which is the boot request. - /// - public override MiniProfiler Start(string profilerName, MiniProfilerBaseOptions options) - { - var first = Interlocked.Exchange(ref _first, 1) == 0; - if (first == false) return base.Start(profilerName, options); - - _startupProfiler = new MiniProfiler("StartupProfiler", options); - CurrentProfiler = _startupProfiler; - return _startupProfiler; - } - - /// - /// Gets the current profiler. - /// - /// - /// If the boot phase is not Booted, then this will return the startup profiler (this), otherwise - /// returns the base class - /// - public override MiniProfiler CurrentProfiler - { - get - { - // if not booting then just use base (fast) - // no lock, _bootPhase is volatile - if (_bootPhase == BootPhase.Booted) - return base.CurrentProfiler; - - // else - try - { - var current = base.CurrentProfiler; - return current ?? _startupProfiler; - } - catch - { - return _startupProfiler; - } - } - - } - } -} diff --git a/src/Umbraco.Web/Macros/MacroRenderer.cs b/src/Umbraco.Web/Macros/MacroRenderer.cs deleted file mode 100644 index 93dc6a14d5..0000000000 --- a/src/Umbraco.Web/Macros/MacroRenderer.cs +++ /dev/null @@ -1,427 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using Microsoft.Extensions.Options; -using Microsoft.Extensions.Logging; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.Models; -using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.Events; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using Umbraco.Core.Macros; -using Umbraco.Core.Models.PublishedContent; -using Umbraco.Core.Security; -using Umbraco.Core.Services; - -namespace Umbraco.Web.Macros -{ - internal class MacroRenderer : IMacroRenderer - { - private readonly IProfilingLogger _profilingLogger; - private readonly ILogger _logger; - private readonly IUmbracoContextAccessor _umbracoContextAccessor; - private readonly ContentSettings _contentSettings; - private readonly ILocalizedTextService _textService; - private readonly AppCaches _appCaches; - private readonly IMacroService _macroService; - private readonly IIOHelper _ioHelper; - private readonly ICookieManager _cookieManager; - private readonly IMemberUserKeyProvider _memberUserKeyProvider; - private readonly ISessionManager _sessionManager; - private readonly IRequestAccessor _requestAccessor; - private readonly IHttpContextAccessor _httpContextAccessor; - - - public MacroRenderer( - IProfilingLogger profilingLogger , - ILogger logger, - IUmbracoContextAccessor umbracoContextAccessor, - IOptions contentSettings, - ILocalizedTextService textService, - AppCaches appCaches, - IMacroService macroService, - IIOHelper ioHelper, - ICookieManager cookieManager, - IMemberUserKeyProvider memberUserKeyProvider, - ISessionManager sessionManager, - IRequestAccessor requestAccessor, - IHttpContextAccessor httpContextAccessor) - { - _profilingLogger = profilingLogger ?? throw new ArgumentNullException(nameof(profilingLogger )); - _logger = logger; - _umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor)); - _contentSettings = contentSettings.Value ?? throw new ArgumentNullException(nameof(contentSettings)); - _textService = textService; - _appCaches = appCaches ?? throw new ArgumentNullException(nameof(appCaches)); - _macroService = macroService ?? throw new ArgumentNullException(nameof(macroService)); - _ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper)); - _cookieManager = cookieManager; - _memberUserKeyProvider = memberUserKeyProvider; - _sessionManager = sessionManager; - _requestAccessor = requestAccessor; - _httpContextAccessor = httpContextAccessor; - } - - #region MacroContent cache - - // gets this macro content cache identifier - private string GetContentCacheIdentifier(MacroModel model, int pageId, string cultureName) - { - var id = new StringBuilder(); - - var alias = model.Alias; - id.AppendFormat("{0}-", alias); - //always add current culture to the key to allow variants to have different cache results - if (!string.IsNullOrEmpty(cultureName)) - { - // are there any unusual culture formats we'd need to handle? - id.AppendFormat("{0}-", cultureName); - } - - if (model.CacheByPage) - id.AppendFormat("{0}-", pageId); - - if (model.CacheByMember) - { - object key = 0; - - if (_umbracoContextAccessor.UmbracoContext.Security.IsAuthenticated()) - { - key = _memberUserKeyProvider.GetMemberProviderUserKey() ?? 0; - } - - id.AppendFormat("m{0}-", key); - } - - foreach (var value in model.Properties.Select(x => x.Value)) - id.AppendFormat("{0}-", value.Length <= 255 ? value : value.Substring(0, 255)); - - return id.ToString(); - } - - // gets this macro content from the cache - // ensuring that it is appropriate to use the cache - private MacroContent GetMacroContentFromCache(MacroModel model) - { - // only if cache is enabled - if (_umbracoContextAccessor.UmbracoContext.InPreviewMode || model.CacheDuration <= 0) return null; - - var cache = _appCaches.RuntimeCache; - var macroContent = cache.GetCacheItem(CacheKeys.MacroContentCacheKey + model.CacheIdentifier); - - if (macroContent == null) return null; - - _logger.LogDebug("Macro content loaded from cache '{MacroCacheId}'", model.CacheIdentifier); - - // ensure that the source has not changed - // note: does not handle dependencies, and never has - var macroSource = GetMacroFile(model); // null if macro is not file-based - if (macroSource != null) - { - if (macroSource.Exists == false) - { - _logger.LogDebug("Macro source does not exist anymore, ignore cache."); - return null; - } - - if (macroContent.Date < macroSource.LastWriteTime) - { - _logger.LogDebug("Macro source has changed, ignore cache."); - return null; - } - } - - return macroContent; - } - - // stores macro content into the cache - private void AddMacroContentToCache(MacroModel model, MacroContent macroContent) - { - // only if cache is enabled - if (_umbracoContextAccessor.UmbracoContext.InPreviewMode || model.CacheDuration <= 0) return; - - // just make sure... - if (macroContent == null) return; - - // do not cache if it should cache by member and there's not member - if (model.CacheByMember) - { - var key = _memberUserKeyProvider.GetMemberProviderUserKey(); - if (key is null) return; - } - - // remember when we cache the content - macroContent.Date = DateTime.Now; - - var cache = _appCaches.RuntimeCache; - cache.Insert( - CacheKeys.MacroContentCacheKey + model.CacheIdentifier, - () => macroContent, - new TimeSpan(0, 0, model.CacheDuration) - ); - - _logger.LogDebug("Macro content saved to cache '{MacroCacheId}'", model.CacheIdentifier); - } - - // gets the macro source file name - // null if the macro is not file-based, or not supported - internal static string GetMacroFileName(MacroModel model) - { - string filename = model.MacroSource; // partial views are saved with their full virtual path - - return string.IsNullOrEmpty(filename) ? null : filename; - } - - // gets the macro source file - // null if macro is not file-based - private FileInfo GetMacroFile(MacroModel model) - { - var filename = GetMacroFileName(model); - if (filename == null) return null; - - var mapped = _ioHelper.MapPath(filename); - if (mapped == null) return null; - - var file = new FileInfo(mapped); - return file.Exists ? file : null; - } - - // updates the model properties values according to the attributes - private static void UpdateMacroModelProperties(MacroModel model, IDictionary macroParams) - { - foreach (var prop in model.Properties) - { - var key = prop.Key.ToLowerInvariant(); - prop.Value = macroParams != null && macroParams.ContainsKey(key) - ? macroParams[key]?.ToString() ?? string.Empty - : string.Empty; - } - } - #endregion - - #region Render/Execute - - public MacroContent Render(string macroAlias, IPublishedContent content, IDictionary macroParams) - { - var m = _appCaches.RuntimeCache.GetCacheItem(CacheKeys.MacroFromAliasCacheKey + macroAlias, () => _macroService.GetByAlias(macroAlias)); - - if (m == null) - throw new InvalidOperationException("No macro found by alias " + macroAlias); - - var macro = new MacroModel(m); - - UpdateMacroModelProperties(macro, macroParams); - return Render(macro, content); - } - - private MacroContent Render(MacroModel macro, IPublishedContent content) - { - if (content == null) throw new ArgumentNullException(nameof(content)); - - var macroInfo = $"Render Macro: {macro.Name}, cache: {macro.CacheDuration}"; - using (_profilingLogger.DebugDuration(macroInfo, "Rendered Macro.")) - { - // parse macro parameters ie replace the special [#key], [$key], etc. syntaxes - foreach (var prop in macro.Properties) - prop.Value = ParseAttribute(prop.Value); - - var cultureName = System.Threading.Thread.CurrentThread.CurrentUICulture.Name; - macro.CacheIdentifier = GetContentCacheIdentifier(macro, content.Id, cultureName); - - // get the macro from cache if it is there - var macroContent = GetMacroContentFromCache(macro); - - // macroContent.IsEmpty may be true, meaning the macro produces no output, - // but still can be cached because its execution did not trigger any error. - // so we need to actually render, only if macroContent is null - if (macroContent != null) - return macroContent; - - // this will take care of errors - // it may throw, if we actually want to throw, so better not - // catch anything here and let the exception be thrown - var attempt = ExecuteMacroOfType(macro, content); - - // by convention ExecuteMacroByType must either throw or return a result - // just check to avoid internal errors - macroContent = attempt.Result; - if (macroContent == null) - throw new Exception("Internal error, ExecuteMacroOfType returned no content."); - - // add to cache if render is successful - // content may be empty but that's not an issue - if (attempt.Success) - { - // write to cache (if appropriate) - AddMacroContentToCache(macro, macroContent); - } - - return macroContent; - } - } - - /// - /// Executes a macro of a given type. - /// - private Attempt ExecuteMacroWithErrorWrapper(MacroModel macro, string msgIn, string msgOut, Func getMacroContent, Func msgErr) - { - using (_profilingLogger.DebugDuration(msgIn, msgOut)) - { - return ExecuteProfileMacroWithErrorWrapper(macro, msgIn, getMacroContent, msgErr); - } - } - - /// - /// Executes a macro of a given type. - /// - private Attempt ExecuteProfileMacroWithErrorWrapper(MacroModel macro, string msgIn, Func getMacroContent, Func msgErr) - { - try - { - return Attempt.Succeed(getMacroContent()); - } - catch (Exception e) - { - _logger.LogWarning(e, "Failed {MsgIn}", msgIn); - - var macroErrorEventArgs = new MacroErrorEventArgs - { - Name = macro.Name, - Alias = macro.Alias, - MacroSource = macro.MacroSource, - Exception = e, - Behaviour = _contentSettings.MacroErrors - }; - - switch (macroErrorEventArgs.Behaviour) - { - case MacroErrorBehaviour.Inline: - // do not throw, eat the exception, display the trace error message - return Attempt.Fail(new MacroContent { Text = msgErr() }, e); - case MacroErrorBehaviour.Silent: - // do not throw, eat the exception, do not display anything - return Attempt.Fail(new MacroContent { Text = string.Empty }, e); - case MacroErrorBehaviour.Content: - // do not throw, eat the exception, display the custom content - return Attempt.Fail(new MacroContent { Text = macroErrorEventArgs.Html ?? string.Empty }, e); - //case MacroErrorBehaviour.Throw: - default: - // see http://issues.umbraco.org/issue/U4-497 at the end - // throw the original exception - throw; - } - } - } - - /// - /// Executes a macro. - /// - /// Returns an attempt that is successful if the macro ran successfully. If the macro failed - /// to run properly, the attempt fails, though it may contain a content. But for instance that content - /// should not be cached. In that case the attempt may also contain an exception. - private Attempt ExecuteMacroOfType(MacroModel model, IPublishedContent content) - { - if (model == null) throw new ArgumentNullException(nameof(model)); - - // ensure that we are running against a published node (ie available in XML) - // that may not be the case if the macro is embedded in a RTE of an unpublished document - - if (content == null) - return Attempt.Fail(new MacroContent { Text = "[macro failed (no content)]" }); - - var textService = _textService; - - return ExecuteMacroWithErrorWrapper(model, - $"Executing PartialView: MacroSource=\"{model.MacroSource}\".", - "Executed PartialView.", - () => ExecutePartialView(model, content), - () => textService.Localize("errors/macroErrorLoadingPartialView", new[] { model.MacroSource })); - } - - - #endregion - - #region Execute engines - - /// - /// Renders a PartialView Macro. - /// - /// The text output of the macro execution. - private MacroContent ExecutePartialView(MacroModel macro, IPublishedContent content) - { - var engine = new PartialViewMacroEngine(_umbracoContextAccessor, _httpContextAccessor, _ioHelper); - return engine.Execute(macro, content); - } - - #endregion - - #region Execution helpers - - // parses attribute value looking for [@requestKey], [%sessionKey] - // supports fallbacks eg "[@requestKey],[%sessionKey],1234" - private string ParseAttribute(string attributeValue) - { - // check for potential querystring/cookie variables - attributeValue = attributeValue.Trim(); - if (attributeValue.StartsWith("[") == false) - return attributeValue; - - var tokens = attributeValue.Split(',').Select(x => x.Trim()).ToArray(); - - // ensure we only process valid input ie each token must be [?x] and not eg a json array - // like [1,2,3] which we don't want to parse - however the last one can be a literal, so - // don't check on the last one which can be just anything - check all previous tokens - - char[] validTypes = { '@', '%' }; - if (tokens.Take(tokens.Length - 1).Any(x => - x.Length < 4 // ie "[?x]".Length - too short - || x[0] != '[' // starts with [ - || x[x.Length - 1] != ']' // ends with ] - || validTypes.Contains(x[1]) == false)) - { - return attributeValue; - } - - foreach (var token in tokens) - { - var isToken = token.Length > 4 && token[0] == '[' && token[token.Length - 1] == ']' && validTypes.Contains(token[1]); - - if (isToken == false) - { - // anything that is not a token is a value, use it - attributeValue = token; - break; - } - - var type = token[1]; - var name = token.Substring(2, token.Length - 3); - - switch (type) - { - case '@': - attributeValue = _requestAccessor.GetRequestValue(name); - break; - case '%': - attributeValue = _sessionManager.GetSessionValue(name); - if (string.IsNullOrEmpty(attributeValue)) - attributeValue = _cookieManager.GetCookieValue(name); - break; - } - - attributeValue = attributeValue?.Trim(); - if (string.IsNullOrEmpty(attributeValue) == false) - break; // got a value, use it - } - - return attributeValue; - } - - #endregion - - } - -} diff --git a/src/Umbraco.Web/Macros/PartialViewMacroController.cs b/src/Umbraco.Web/Macros/PartialViewMacroController.cs deleted file mode 100644 index 21d7b3292c..0000000000 --- a/src/Umbraco.Web/Macros/PartialViewMacroController.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Web.Mvc; -using Umbraco.Web.Models; -using Umbraco.Web.Mvc; -using System.Linq; -using Umbraco.Core.Composing; -using Umbraco.Core.Models.PublishedContent; - -namespace Umbraco.Web.Macros -{ - /// - /// Controller to render macro content for Partial View Macros - /// - [MergeParentContextViewData] - [HideFromTypeFinder] // explicitly used: do *not* find and register it! - internal class PartialViewMacroController : Controller - { - private readonly MacroModel _macro; - private readonly IPublishedContent _content; - - public PartialViewMacroController(MacroModel macro, IPublishedContent content) - { - _macro = macro; - _content = content; - } - - /// - /// Child action to render a macro - /// - /// - [ChildActionOnly] - public PartialViewResult Index() - { - var model = new PartialViewMacroModel( - _content, - _macro.Id, - _macro.Alias, - _macro.Name, - _macro.Properties.ToDictionary(x => x.Key, x => (object)x.Value)); - return PartialView(_macro.MacroSource, model); - } - } -} diff --git a/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs b/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs deleted file mode 100644 index 0773bc31ca..0000000000 --- a/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Web; -using System.Web.Mvc; -using System.Web.Routing; -using System.Web.WebPages; -using Umbraco.Web.Mvc; -using Umbraco.Core; -using Umbraco.Core.IO; -using Umbraco.Core.Models.PublishedContent; -using Umbraco.Web.Composing; - -namespace Umbraco.Web.Macros -{ - /// - /// A macro engine using MVC Partial Views to execute. - /// - public class PartialViewMacroEngine - { - private readonly IHttpContextAccessor _httpContextAccessor; - private readonly IIOHelper _ioHelper; - private readonly Func _getUmbracoContext; - - public PartialViewMacroEngine(IUmbracoContextAccessor umbracoContextAccessor, IHttpContextAccessor httpContextAccessor, IIOHelper ioHelper) - { - _httpContextAccessor = httpContextAccessor; - _ioHelper = ioHelper; - - _getUmbracoContext = () => - { - var context = umbracoContextAccessor.UmbracoContext; - if (context == null) - throw new InvalidOperationException($"The {GetType()} cannot execute with a null UmbracoContext.Current reference."); - return context; - }; - } - - public bool Validate(string code, string tempFileName, IPublishedContent currentPage, out string errorMessage) - { - var temp = GetVirtualPathFromPhysicalPath(tempFileName); - try - { - CompileAndInstantiate(temp); - } - catch (Exception exception) - { - errorMessage = exception.Message; - return false; - } - errorMessage = string.Empty; - return true; - } - - public MacroContent Execute(MacroModel macro, IPublishedContent content) - { - if (macro == null) throw new ArgumentNullException(nameof(macro)); - if (content == null) throw new ArgumentNullException(nameof(content)); - if (macro.MacroSource.IsNullOrWhiteSpace()) throw new ArgumentException("The MacroSource property of the macro object cannot be null or empty"); - - var httpContext = _httpContextAccessor.GetRequiredHttpContext(); - var umbCtx = _getUmbracoContext(); - var routeVals = new RouteData(); - routeVals.Values.Add("controller", "PartialViewMacro"); - routeVals.Values.Add("action", "Index"); - routeVals.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbCtx); //required for UmbracoViewPage - - //lets render this controller as a child action - var viewContext = new ViewContext { ViewData = new ViewDataDictionary() }; - //try and extract the current view context from the route values, this would be set in the UmbracoViewPage or in - // the UmbracoPageResult if POSTing to an MVC controller but rendering in Webforms - if (httpContext.Request.RequestContext.RouteData.DataTokens.ContainsKey(Mvc.Constants.DataTokenCurrentViewContext)) - { - viewContext = (ViewContext)httpContext.Request.RequestContext.RouteData.DataTokens[Mvc.Constants.DataTokenCurrentViewContext]; - } - routeVals.DataTokens.Add("ParentActionViewContext", viewContext); - - var request = new RequestContext(httpContext, routeVals); - - string output = String.Empty; - - using (var controller = new PartialViewMacroController(macro, content)) - { - controller.ViewData = viewContext.ViewData; - - controller.ControllerContext = new ControllerContext(request, controller); - - //call the action to render - var result = controller.Index(); - output = controller.RenderViewResultAsString(result); - } - - return new MacroContent { Text = output }; - } - - private string GetVirtualPathFromPhysicalPath(string physicalPath) - { - var rootpath = _ioHelper.MapPath("~/"); - physicalPath = physicalPath.Replace(rootpath, ""); - physicalPath = physicalPath.Replace("\\", "/"); - return "~/" + physicalPath; - } - - private static PartialViewMacroPage CompileAndInstantiate(string virtualPath) - { - //Compile Razor - We Will Leave This To ASP.NET Compilation Engine & ASP.NET WebPages - //Security in medium trust is strict around here, so we can only pass a virtual file path - //ASP.NET Compilation Engine caches returned types - //Changed From BuildManager As Other Properties Are Attached Like Context Path/ - var webPageBase = WebPageBase.CreateInstanceFromVirtualPath(virtualPath); - var webPage = webPageBase as PartialViewMacroPage; - if (webPage == null) - throw new InvalidCastException("All Partial View Macro views must inherit from " + typeof(PartialViewMacroPage).FullName); - return webPage; - } - - } - -} diff --git a/src/Umbraco.Web/Mvc/ContainerControllerFactory.cs b/src/Umbraco.Web/Mvc/ContainerControllerFactory.cs deleted file mode 100644 index 914e4bbb70..0000000000 --- a/src/Umbraco.Web/Mvc/ContainerControllerFactory.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Web.Mvc; -using System.Web.Routing; -using Umbraco.Core.Composing; - -namespace Umbraco.Web.Mvc -{ - public class ContainerControllerFactory : DefaultControllerFactory - { - private readonly Lazy _factory; - - public ContainerControllerFactory(Lazy factory) - { - _factory = factory; - } - - protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) - { - try - { - return (IController) _factory.Value.GetInstance(controllerType); - } - catch (Exception e) - { - throw new Exception($"Failed to create an instance of controller type {controllerType.FullName} (see inner exception).", e); - } - } - - public override void ReleaseController(IController controller) - { - _factory.Value.Release(controller); - } - } -} diff --git a/src/Umbraco.Web/Mvc/ContentModelBinder.cs b/src/Umbraco.Web/Mvc/ContentModelBinder.cs deleted file mode 100644 index 376ce737b4..0000000000 --- a/src/Umbraco.Web/Mvc/ContentModelBinder.cs +++ /dev/null @@ -1,222 +0,0 @@ -using System; -using System.Text; -using System.Web; -using System.Web.Mvc; -using Umbraco.Core; -using Umbraco.Core.Models.PublishedContent; -using Umbraco.Web.Composing; -using Umbraco.Web.Models; - -namespace Umbraco.Web.Mvc -{ - /// - /// Maps view models, supporting mapping to and from any IPublishedContent or IContentModel. - /// - /// Migrated to .NET Core - public class ContentModelBinder : DefaultModelBinder, IModelBinderProvider - { - // use Instance - private ContentModelBinder() { } - - public static ContentModelBinder Instance = new ContentModelBinder(); - - /// - /// Binds the model to a value by using the specified controller context and binding context. - /// - /// - /// The bound value. - /// - /// The controller context.The binding context. - public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) - { - object model; - if (controllerContext.RouteData.DataTokens.TryGetValue(Core.Constants.Web.UmbracoDataToken, out model) == false) - return null; - - // this model binder deals with IContentModel and IPublishedContent by extracting the model from the route's - // datatokens. This data token is set in 2 places: RenderRouteHandler, UmbracoVirtualNodeRouteHandler - // and both always set the model to an instance of `ContentMOdel`. So if this isn't an instance of IContentModel then - // we need to let the DefaultModelBinder deal with the logic. - var contentModel = model as IContentModel; - if (contentModel == null) - { - model = base.BindModel(controllerContext, bindingContext); - if (model == null) return null; - } - - //if for any reason the model is not either IContentModel or IPublishedContent, then we return since those are the only - // types this binder is dealing with. - if ((model is IContentModel) == false && (model is IPublishedContent) == false) return null; - - return BindModel(model, bindingContext.ModelType); - } - - // source is the model that we have - // modelType is the type of the model that we need to bind to - // - // create a model object of the modelType by mapping: - // { ContentModel, ContentModel, IPublishedContent } - // to - // { ContentModel, ContentModel, IPublishedContent } - // - public static object BindModel(object source, Type modelType) - { - // null model, return - if (source == null) return null; - - // if types already match, return - var sourceType = source.GetType(); - if (sourceType.Inherits(modelType)) // includes == - return source; - - // try to grab the content - var sourceContent = source as IPublishedContent; // check if what we have is an IPublishedContent - if (sourceContent == null && sourceType.Implements()) - { - // else check if it's an IContentModel, and get the content - sourceContent = ((IContentModel)source).Content; - } - if (sourceContent == null) - { - // else check if we can convert it to a content - var attempt1 = source.TryConvertTo(); - if (attempt1.Success) sourceContent = attempt1.Result; - } - - // if we have a content - if (sourceContent != null) - { - // if model is IPublishedContent, check content type and return - if (modelType.Implements()) - { - if ((sourceContent.GetType().Inherits(modelType)) == false) - ThrowModelBindingException(true, false, sourceContent.GetType(), modelType); - return sourceContent; - } - - // if model is ContentModel, create and return - if (modelType == typeof(ContentModel)) - { - return new ContentModel(sourceContent); - } - - // if model is ContentModel, check content type, then create and return - if (modelType.IsGenericType && modelType.GetGenericTypeDefinition() == typeof(ContentModel<>)) - { - var targetContentType = modelType.GetGenericArguments()[0]; - if ((sourceContent.GetType().Inherits(targetContentType)) == false) - ThrowModelBindingException(true, true, sourceContent.GetType(), targetContentType); - return Activator.CreateInstance(modelType, sourceContent); - } - } - - // last chance : try to convert - var attempt2 = source.TryConvertTo(modelType); - if (attempt2.Success) return attempt2.Result; - - // fail - ThrowModelBindingException(false, false, sourceType, modelType); - return null; - } - - private static void ThrowModelBindingException(bool sourceContent, bool modelContent, Type sourceType, Type modelType) - { - var msg = new StringBuilder(); - - // prepare message - msg.Append("Cannot bind source"); - if (sourceContent) msg.Append(" content"); - msg.Append(" type "); - msg.Append(sourceType.FullName); - msg.Append(" to model"); - if (modelContent) msg.Append(" content"); - msg.Append(" type "); - msg.Append(modelType.FullName); - msg.Append("."); - - // raise event, to give model factories a chance at reporting - // the error with more details, and optionally request that - // the application restarts. - - var args = new ModelBindingArgs(sourceType, modelType, msg); - ModelBindingException?.Invoke(Instance, args); - - // TODO: with all of the tests I've done i don't think restarting the app here is required anymore, - // when I don't have this code enabled and i get a model binding error and just refresh, it fixes itself. - // We'll leave this for now though. - if (args.Restart) - { - msg.Append(" The application is restarting now."); - - var context = HttpContext.Current; - if (context == null) - { - AppDomain.Unload(AppDomain.CurrentDomain); - } - else - { - Current.UmbracoApplicationLifetime.Restart(); - } - - - } - - throw new ModelBindingException(msg.ToString()); - } - - public IModelBinder GetBinder(Type modelType) - { - // can bind to ContentModel (exact type match) - if (modelType == typeof(ContentModel)) return this; - - // can bind to ContentModel (exact generic type match) - if (modelType.IsGenericType && modelType.GetGenericTypeDefinition() == typeof(ContentModel<>)) return this; - - // can bind to TContent where TContent : IPublishedContent (any IPublishedContent implementation) - if (typeof(IPublishedContent).IsAssignableFrom(modelType)) return this; - return null; - } - - /// - /// Contains event data for the event. - /// - public class ModelBindingArgs : EventArgs - { - /// - /// Initializes a new instance of the class. - /// - public ModelBindingArgs(Type sourceType, Type modelType, StringBuilder message) - { - SourceType = sourceType; - ModelType = modelType; - Message = message; - } - - /// - /// Gets the type of the source object. - /// - public Type SourceType { get; set; } - - /// - /// Gets the type of the view model. - /// - public Type ModelType { get; set; } - - /// - /// Gets the message string builder. - /// - /// Handlers of the event can append text to the message. - public StringBuilder Message { get; } - - /// - /// Gets or sets a value indicating whether the application should restart. - /// - public bool Restart { get; set; } - } - - /// - /// Occurs on model binding exceptions. - /// - public static event EventHandler ModelBindingException; - } -} diff --git a/src/Umbraco.Web/Mvc/ControllerFactoryExtensions.cs b/src/Umbraco.Web/Mvc/ControllerFactoryExtensions.cs index eb39cb8faa..a69b09efe0 100644 --- a/src/Umbraco.Web/Mvc/ControllerFactoryExtensions.cs +++ b/src/Umbraco.Web/Mvc/ControllerFactoryExtensions.cs @@ -20,8 +20,10 @@ namespace Umbraco.Web.Mvc /// internal static Type GetControllerTypeInternal(this IControllerFactory factory, RequestContext requestContext, string controllerName) { - if (factory is MasterControllerFactory controllerFactory) - return controllerFactory.GetControllerTypeInternal(requestContext, controllerName); + + //TODO Reintroduce for netcore + // if (factory is MasterControllerFactory controllerFactory) + // return controllerFactory.GetControllerTypeInternal(requestContext, controllerName); //we have no choice but to instantiate the controller var instance = factory.CreateController(requestContext, controllerName); diff --git a/src/Umbraco.Web/Mvc/FilteredControllerFactoryCollection.cs b/src/Umbraco.Web/Mvc/FilteredControllerFactoryCollection.cs deleted file mode 100644 index 1c2d140379..0000000000 --- a/src/Umbraco.Web/Mvc/FilteredControllerFactoryCollection.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.Composing; - -namespace Umbraco.Web.Mvc -{ - public class FilteredControllerFactoryCollection : BuilderCollectionBase - { - public FilteredControllerFactoryCollection(IEnumerable items) - : base(items) - { } - } -} diff --git a/src/Umbraco.Web/Mvc/FilteredControllerFactoryCollectionBuilder.cs b/src/Umbraco.Web/Mvc/FilteredControllerFactoryCollectionBuilder.cs deleted file mode 100644 index 2c4182beac..0000000000 --- a/src/Umbraco.Web/Mvc/FilteredControllerFactoryCollectionBuilder.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Umbraco.Core.Composing; - -namespace Umbraco.Web.Mvc -{ - public class FilteredControllerFactoryCollectionBuilder : OrderedCollectionBuilderBase - { - protected override FilteredControllerFactoryCollectionBuilder This => this; - } -} diff --git a/src/Umbraco.Web/Mvc/IFilteredControllerFactory.cs b/src/Umbraco.Web/Mvc/IFilteredControllerFactory.cs deleted file mode 100644 index a2cc53a104..0000000000 --- a/src/Umbraco.Web/Mvc/IFilteredControllerFactory.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Linq; -using System.Web.Mvc; -using System.Web.Routing; - -namespace Umbraco.Web.Mvc -{ - - public interface IFilteredControllerFactory : IControllerFactory - { - /// - /// Determines whether this instance can handle the specified request. - /// - /// The request. - /// true if this instance can handle the specified request; otherwise, false. - /// - bool CanHandle(RequestContext request); - - } -} diff --git a/src/Umbraco.Web/Mvc/MasterControllerFactory.cs b/src/Umbraco.Web/Mvc/MasterControllerFactory.cs deleted file mode 100644 index cfc931fc71..0000000000 --- a/src/Umbraco.Web/Mvc/MasterControllerFactory.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.Linq; -using System.Web.Mvc; -using System.Web.Routing; -using Umbraco.Core.Composing; -using Umbraco.Web.Composing; - -namespace Umbraco.Web.Mvc -{ - /// - /// A controller factory which uses an internal list of in order to invoke - /// different controller factories dependent upon their implementation of for the current - /// request. Allows circumvention of MVC3's singly registered IControllerFactory. - /// - /// - internal class MasterControllerFactory : ContainerControllerFactory - { - private readonly Func _factoriesAccessor; - private FilteredControllerFactoryCollection _factories; - - /// - /// Initializes a new instance of the with a factories accessor. - /// - /// The factories accessor. - public MasterControllerFactory(Func factoriesAccessor) - : base(new Lazy(() => Current.Factory)) - { - // note - // because the MasterControllerFactory needs to be ctored to be assigned to - // ControllerBuilder.Current when setting up Mvc and WebApi, it cannot be ctored by - // the IoC container - and yet we don't want that ctor to resolve the factories - // as that happen before everything is configured - so, passing a factories - // accessor function. - - _factoriesAccessor = factoriesAccessor; - } - - private IFilteredControllerFactory FactoryForRequest(RequestContext context) - { - if (_factories == null) _factories = _factoriesAccessor(); - return _factories.FirstOrDefault(x => x.CanHandle(context)); - } - - /// - /// Creates the specified controller by using the specified request context. - /// - /// The context of the HTTP request, which includes the HTTP context and route data. - /// The name of the controller. - /// The controller. - /// The parameter is null. - /// - /// The parameter is null or empty. - /// - public override IController CreateController(RequestContext requestContext, string controllerName) - { - var factory = FactoryForRequest(requestContext); - return factory != null - ? factory.CreateController(requestContext, controllerName) - : base.CreateController(requestContext, controllerName); - } - - /// - /// Retrieves the controller type for the specified name and request context. - /// - /// - /// - /// The controller type. - /// - /// The context of the HTTP request, which includes the HTTP context and route data. - /// The name of the controller. - internal Type GetControllerTypeInternal(RequestContext requestContext, string controllerName) - { - var factory = FactoryForRequest(requestContext); - if (factory != null) - { - //check to see if the factory is of type UmbracoControllerFactory which exposes the GetControllerType method so we don't have to create - // an instance of the controller to figure out what it is. This is a work around for not having a breaking change for: - // http://issues.umbraco.org/issue/U4-1726 - - if (factory is UmbracoControllerFactory umbFactory) - return umbFactory.GetControllerType(requestContext, controllerName); - - //we have no choice but to instantiate the controller - var instance = factory.CreateController(requestContext, controllerName); - var controllerType = instance?.GetType(); - factory.ReleaseController(instance); - - return controllerType; - } - - return GetControllerType(requestContext, controllerName); - } - - /// - /// Releases the specified controller. - /// - /// The controller to release. - /// - public override void ReleaseController(IController icontroller) - { - var released = false; - - if (icontroller is Controller controller) - { - var requestContext = controller.ControllerContext.RequestContext; - var factory = FactoryForRequest(requestContext); - if (factory != null) - { - factory.ReleaseController(controller); - released = true; - } - } - - if (released == false) - base.ReleaseController(icontroller); - } - } -} diff --git a/src/Umbraco.Web/Mvc/ModelBindingException.cs b/src/Umbraco.Web/Mvc/ModelBindingException.cs deleted file mode 100644 index 548b548d4e..0000000000 --- a/src/Umbraco.Web/Mvc/ModelBindingException.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace Umbraco.Web.Mvc -{ - /// - /// The exception that is thrown when an error occurs while binding a source to a model. - /// - /// - [Serializable] - public class ModelBindingException : Exception - { - /// - /// Initializes a new instance of the class. - /// - public ModelBindingException() - { } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public ModelBindingException(string message) - : base(message) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception, or a null reference ( in Visual Basic) if no inner exception is specified. - public ModelBindingException(string message, Exception innerException) - : base(message, innerException) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - protected ModelBindingException(SerializationInfo info, StreamingContext context) - : base(info, context) - { } - } -} diff --git a/src/Umbraco.Web/Mvc/ModelBindingExceptionFilter.cs b/src/Umbraco.Web/Mvc/ModelBindingExceptionFilter.cs deleted file mode 100644 index b189867a89..0000000000 --- a/src/Umbraco.Web/Mvc/ModelBindingExceptionFilter.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Configuration; -using System.Net; -using System.Text.RegularExpressions; -using System.Web.Mvc; -using Microsoft.Extensions.Options; -using Umbraco.Core.Configuration; -using Umbraco.Core; -using Umbraco.Core.Configuration.Models; -using Umbraco.Web.Composing; - -namespace Umbraco.Web.Mvc -{ - /// - /// An exception filter checking if we get a or with the same model. - /// In which case it returns a redirect to the same page after 1 sec if not in debug mode. - /// - /// - /// This is only enabled when running PureLive - /// - /// Migrated to .NET Core - internal class ModelBindingExceptionFilter : FilterAttribute, IExceptionFilter - { - private static readonly Regex GetPublishedModelsTypesRegex = new Regex("Umbraco.Web.PublishedModels.(\\w+)", RegexOptions.Compiled); - - public void OnException(ExceptionContext filterContext) - { - var settings = Current.Factory.GetInstance>().Value; - var disabled = settings?.Disabled ?? false; - if (Current.PublishedModelFactory.IsLiveFactory() - && !disabled - && !filterContext.ExceptionHandled - && ((filterContext.Exception is ModelBindingException || filterContext.Exception is InvalidCastException) - && IsMessageAboutTheSameModelType(filterContext.Exception.Message))) - { - filterContext.HttpContext.Response.Headers.Add(HttpResponseHeader.RetryAfter.ToString(), "1"); - filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.RawUrl, false); - - filterContext.ExceptionHandled = true; - } - } - - /// - /// Returns true if the message is about two models with the same name. - /// - /// - /// Message could be something like: - /// - /// InvalidCastException: - /// [A]Umbraco.Web.PublishedModels.Home cannot be cast to [B]Umbraco.Web.PublishedModels.Home. Type A originates from 'App_Web_all.generated.cs.8f9494c4.rtdigm_z, Version=0.0.0.3, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\Users\User\AppData\Local\Temp\Temporary ASP.NET Files\root\c5c63f4d\c168d9d4\App_Web_all.generated.cs.8f9494c4.rtdigm_z.dll'. Type B originates from 'App_Web_all.generated.cs.8f9494c4.rbyqlplu, Version=0.0.0.5, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\Users\User\AppData\Local\Temp\Temporary ASP.NET Files\root\c5c63f4d\c168d9d4\App_Web_all.generated.cs.8f9494c4.rbyqlplu.dll'. - /// - /// - /// ModelBindingException: - /// Cannot bind source content type Umbraco.Web.PublishedModels.Home to model type Umbraco.Web.PublishedModels.Home. Both view and content models are PureLive, with different versions. The application is in an unstable state and is going to be restarted. The application is restarting now. - /// - /// - private bool IsMessageAboutTheSameModelType(string exceptionMessage) - { - var matches = GetPublishedModelsTypesRegex.Matches(exceptionMessage); - - if (matches.Count >= 2) - { - return string.Equals(matches[0].Value, matches[1].Value, StringComparison.InvariantCulture); - } - - return false; - } - } -} diff --git a/src/Umbraco.Web/Mvc/PreRenderViewActionFilterAttribute.cs b/src/Umbraco.Web/Mvc/PreRenderViewActionFilterAttribute.cs deleted file mode 100644 index 2e659eccf6..0000000000 --- a/src/Umbraco.Web/Mvc/PreRenderViewActionFilterAttribute.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Web.Mvc; - -namespace Umbraco.Web.Mvc -{ - /// Migrated already to .Net Core - public class PreRenderViewActionFilterAttribute : ActionFilterAttribute - { - public override void OnActionExecuted(ActionExecutedContext filterContext) - { - var umbController = filterContext.Controller as Controller; - if (umbController == null) - { - return; - } - - var result = filterContext.Result as ViewResultBase; - if (result == null) - { - return; - } - - var model = result.Model; - if (model == null) - { - return; - } - - var args = new ActionExecutedEventArgs(umbController, model); - OnActionExecuted(args); - - if (args.Model != model) - { - result.ViewData.Model = args.Model; - } - - base.OnActionExecuted(filterContext); - } - - - public static event EventHandler ActionExecuted; - - private static void OnActionExecuted(ActionExecutedEventArgs e) - { - EventHandler handler = ActionExecuted; - if (handler != null) handler(null, e); - } - } -} diff --git a/src/Umbraco.Web/Mvc/RenderControllerFactory.cs b/src/Umbraco.Web/Mvc/RenderControllerFactory.cs index c9734e24b0..091ace4d98 100644 --- a/src/Umbraco.Web/Mvc/RenderControllerFactory.cs +++ b/src/Umbraco.Web/Mvc/RenderControllerFactory.cs @@ -1,45 +1,45 @@ -using System.Web.Mvc; -using System.Web.Routing; - -namespace Umbraco.Web.Mvc -{ - /// - /// A controller factory for the render pipeline of Umbraco. This controller factory tries to create a controller with the supplied - /// name, and falls back to UmbracoController if none was found. - /// - /// - public class RenderControllerFactory : UmbracoControllerFactory - { - /// - /// Determines whether this instance can handle the specified request. - /// - /// The request. - /// true if this instance can handle the specified request; otherwise, false. - /// - public override bool CanHandle(RequestContext request) - { - var dataToken = request.RouteData.DataTokens["area"]; - return dataToken == null || string.IsNullOrWhiteSpace(dataToken.ToString()); - } - - /// - /// Creates the controller - /// - /// - /// - /// - /// - /// We always set the correct ActionInvoker on our custom created controller, this is very important for route hijacking! - /// - public override IController CreateController(RequestContext requestContext, string controllerName) - { - var instance = base.CreateController(requestContext, controllerName); - if (instance is Controller controllerInstance) - { - //set the action invoker! - controllerInstance.ActionInvoker = new RenderActionInvoker(); - } - return instance; - } - } -} +// using System.Web.Mvc; +// using System.Web.Routing; +// +// namespace Umbraco.Web.Mvc +// { +// /// +// /// A controller factory for the render pipeline of Umbraco. This controller factory tries to create a controller with the supplied +// /// name, and falls back to UmbracoController if none was found. +// /// +// /// +// public class RenderControllerFactory : UmbracoControllerFactory +// { +// /// +// /// Determines whether this instance can handle the specified request. +// /// +// /// The request. +// /// true if this instance can handle the specified request; otherwise, false. +// /// +// public override bool CanHandle(RequestContext request) +// { +// var dataToken = request.RouteData.DataTokens["area"]; +// return dataToken == null || string.IsNullOrWhiteSpace(dataToken.ToString()); +// } +// +// /// +// /// Creates the controller +// /// +// /// +// /// +// /// +// /// +// /// We always set the correct ActionInvoker on our custom created controller, this is very important for route hijacking! +// /// +// public override IController CreateController(RequestContext requestContext, string controllerName) +// { +// var instance = base.CreateController(requestContext, controllerName); +// if (instance is Controller controllerInstance) +// { +// //set the action invoker! +// controllerInstance.ActionInvoker = new RenderActionInvoker(); +// } +// return instance; +// } +// } +// } diff --git a/src/Umbraco.Web/Mvc/UmbracoControllerFactory.cs b/src/Umbraco.Web/Mvc/UmbracoControllerFactory.cs index 325f18d957..b4dde6c540 100644 --- a/src/Umbraco.Web/Mvc/UmbracoControllerFactory.cs +++ b/src/Umbraco.Web/Mvc/UmbracoControllerFactory.cs @@ -1,88 +1,88 @@ -using System; -using System.Web.Mvc; -using System.Web.Routing; -using System.Web.SessionState; -using Umbraco.Core; -using Umbraco.Core.Composing; -using Umbraco.Web.Composing; - -namespace Umbraco.Web.Mvc -{ - /// - /// Abstract filtered controller factory used for all Umbraco controller factory implementations - /// - public abstract class UmbracoControllerFactory : IFilteredControllerFactory - { - private readonly OverridenDefaultControllerFactory _innerFactory = new OverridenDefaultControllerFactory(); - - public abstract bool CanHandle(RequestContext request); - - public virtual Type GetControllerType(RequestContext requestContext, string controllerName) - { - return _innerFactory.GetControllerType(requestContext, controllerName); - } - - /// - /// Creates the specified controller by using the specified request context. - /// - /// - /// The controller. - /// - /// The request context.The name of the controller. - public virtual IController CreateController(RequestContext requestContext, string controllerName) - { - var controllerType = GetControllerType(requestContext, controllerName) ?? - _innerFactory.GetControllerType( - requestContext, - ControllerExtensions.GetControllerName(Current.DefaultRenderMvcControllerType)); - - return _innerFactory.GetControllerInstance(requestContext, controllerType); - } - - /// - /// Gets the controller's session behavior. - /// - /// - /// The controller's session behavior. - /// - /// The request context.The name of the controller whose session behavior you want to get. - public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) - { - return ((IControllerFactory)_innerFactory).GetControllerSessionBehavior(requestContext, controllerName); - } - - /// - /// Releases the specified controller. - /// - /// The controller. - public virtual void ReleaseController(IController controller) - { - _innerFactory.ReleaseController(controller); - } - - /// - /// By default, only exposes which throws an exception - /// if the controller is not found. Since we want to try creating a controller, and then fall back to if one isn't found, - /// this nested class changes the visibility of 's internal methods in order to not have to rely on a try-catch. - /// - /// - internal class OverridenDefaultControllerFactory : ContainerControllerFactory - { - public OverridenDefaultControllerFactory() - : base(new Lazy(() => Current.Factory)) - { } - - public new IController GetControllerInstance(RequestContext requestContext, Type controllerType) - { - return base.GetControllerInstance(requestContext, controllerType); - } - - public new Type GetControllerType(RequestContext requestContext, string controllerName) - { - return controllerName.IsNullOrWhiteSpace() - ? null - : base.GetControllerType(requestContext, controllerName); - } - } - } -} +// using System; +// using System.Web.Mvc; +// using System.Web.Routing; +// using System.Web.SessionState; +// using Umbraco.Core; +// using Umbraco.Core.Composing; +// using Umbraco.Web.Composing; +// +// namespace Umbraco.Web.Mvc +// { +// /// +// /// Abstract filtered controller factory used for all Umbraco controller factory implementations +// /// +// public abstract class UmbracoControllerFactory : IFilteredControllerFactory +// { +// private readonly OverridenDefaultControllerFactory _innerFactory = new OverridenDefaultControllerFactory(); +// +// public abstract bool CanHandle(RequestContext request); +// +// public virtual Type GetControllerType(RequestContext requestContext, string controllerName) +// { +// return _innerFactory.GetControllerType(requestContext, controllerName); +// } +// +// /// +// /// Creates the specified controller by using the specified request context. +// /// +// /// +// /// The controller. +// /// +// /// The request context.The name of the controller. +// public virtual IController CreateController(RequestContext requestContext, string controllerName) +// { +// var controllerType = GetControllerType(requestContext, controllerName) ?? +// _innerFactory.GetControllerType( +// requestContext, +// ControllerExtensions.GetControllerName(Current.DefaultRenderMvcControllerType)); +// +// return _innerFactory.GetControllerInstance(requestContext, controllerType); +// } +// +// /// +// /// Gets the controller's session behavior. +// /// +// /// +// /// The controller's session behavior. +// /// +// /// The request context.The name of the controller whose session behavior you want to get. +// public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) +// { +// return ((IControllerFactory)_innerFactory).GetControllerSessionBehavior(requestContext, controllerName); +// } +// +// /// +// /// Releases the specified controller. +// /// +// /// The controller. +// public virtual void ReleaseController(IController controller) +// { +// _innerFactory.ReleaseController(controller); +// } +// +// /// +// /// By default, only exposes which throws an exception +// /// if the controller is not found. Since we want to try creating a controller, and then fall back to if one isn't found, +// /// this nested class changes the visibility of 's internal methods in order to not have to rely on a try-catch. +// /// +// /// +// internal class OverridenDefaultControllerFactory : ContainerControllerFactory +// { +// public OverridenDefaultControllerFactory() +// : base(new Lazy(() => Current.Factory)) +// { } +// +// public new IController GetControllerInstance(RequestContext requestContext, Type controllerType) +// { +// return base.GetControllerInstance(requestContext, controllerType); +// } +// +// public new Type GetControllerType(RequestContext requestContext, string controllerName) +// { +// return controllerName.IsNullOrWhiteSpace() +// ? null +// : base.GetControllerType(requestContext, controllerName); +// } +// } +// } +// } diff --git a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs index f461fb9a22..7eff581bab 100644 --- a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs +++ b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs @@ -143,59 +143,7 @@ namespace Umbraco.Web.Mvc if (ViewContext.RouteData.DataTokens.ContainsKey(Constants.DataTokenCurrentViewContext) == false) ViewContext.RouteData.DataTokens.Add(Constants.DataTokenCurrentViewContext, ViewContext); } - - // maps model - protected override void SetViewData(ViewDataDictionary viewData) - { - // capture the model before we tinker with the viewData - var viewDataModel = viewData.Model; - - // map the view data (may change its type, may set model to null) - viewData = MapViewDataDictionary(viewData, typeof (TModel)); - - // bind the model - viewData.Model = ContentModelBinder.BindModel(viewDataModel, typeof (TModel)); - - // set the view data - base.SetViewData(viewData); - } - - // viewData is the ViewDataDictionary (maybe ) that we have - // modelType is the type of the model that we need to bind to - // - // figure out whether viewData can accept modelType else replace it - // - private static ViewDataDictionary MapViewDataDictionary(ViewDataDictionary viewData, Type modelType) - { - var viewDataType = viewData.GetType(); - - // if viewData is not generic then it is a simple ViewDataDictionary instance and its - // Model property is of type 'object' and will accept anything, so it is safe to use - // viewData - if (viewDataType.IsGenericType == false) - return viewData; - - // ensure it is the proper generic type - var def = viewDataType.GetGenericTypeDefinition(); - if (def != typeof(ViewDataDictionary<>)) - throw new Exception("Could not map viewData of type \"" + viewDataType.FullName + "\"."); - - // get the viewData model type and compare with the actual view model type: - // viewData is ViewDataDictionary and we will want to assign an - // object of type modelType to the Model property of type viewDataModelType, we - // need to check whether that is possible - var viewDataModelType = viewDataType.GenericTypeArguments[0]; - - if (viewDataModelType.IsAssignableFrom(modelType)) - return viewData; - - // if not possible then we need to create a new ViewDataDictionary - var nViewDataType = typeof(ViewDataDictionary<>).MakeGenericType(modelType); - var tViewData = new ViewDataDictionary(viewData) { Model = null }; // temp view data to copy values - var nViewData = (ViewDataDictionary)Activator.CreateInstance(nViewDataType, tViewData); - return nViewData; - } - + /// /// This will detect the end /body tag and insert the preview badge if in preview mode /// diff --git a/src/Umbraco.Web/Runtime/WebInitialComponent.cs b/src/Umbraco.Web/Runtime/WebInitialComponent.cs index a5c7db12c9..d02ccdd01e 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComponent.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComponent.cs @@ -89,16 +89,13 @@ namespace Umbraco.Web.Runtime MvcHandler.DisableMvcResponseHeader = true; // set master controller factory - var controllerFactory = new MasterControllerFactory(() => Current.FilteredControllerFactories); - ControllerBuilder.Current.SetControllerFactory(controllerFactory); + // var controllerFactory = new MasterControllerFactory(() => Current.FilteredControllerFactories); + // ControllerBuilder.Current.SetControllerFactory(controllerFactory); // set the render & plugin view engines ViewEngines.Engines.Add(new RenderViewEngine(_hostingEnvironment)); ViewEngines.Engines.Add(new PluginViewEngine()); - - //set model binder - ModelBinderProviders.BinderProviders.Add(ContentModelBinder.Instance); // is a provider - + ////add the profiling action filter //GlobalFilters.Filters.Add(new ProfilingActionFilter()); diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs index 591a3698e7..8d3b416012 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs @@ -54,24 +54,20 @@ namespace Umbraco.Web.Runtime composition.RegisterUnique(); // configure the container for web - composition.ConfigureForWeb(); + //composition.ConfigureForWeb(); composition // TODO: This will depend on if we use ServiceBasedControllerActivator - see notes in Startup.cs - .ComposeUmbracoControllers(GetType().Assembly) + //.ComposeUmbracoControllers(GetType().Assembly) .SetDefaultRenderMvcController(); // default controller for template views //we need to eagerly scan controller types since they will need to be routed composition.WithCollectionBuilder() .Add(composition.TypeLoader.GetSurfaceControllers()); - // add all known factories, devs can then modify this list on application - // startup either by binding to events or in their own global.asax - composition.FilteredControllerFactory() - .Append(); // auto-register views - composition.RegisterAuto(typeof(UmbracoViewPage<>)); + //composition.RegisterAuto(typeof(UmbracoViewPage<>)); } } } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index d7bd025e2a..a2a15ada05 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -144,16 +144,11 @@ - - - - - @@ -168,13 +163,8 @@ - - - - - @@ -209,7 +199,6 @@ - @@ -220,10 +209,7 @@ - - - @@ -237,7 +223,6 @@ - @@ -261,7 +246,6 @@ - @@ -336,11 +320,8 @@ - - - diff --git a/src/Umbraco.Web/UmbracoApplication.cs b/src/Umbraco.Web/UmbracoApplication.cs index 8f6231b22a..90b2569c67 100644 --- a/src/Umbraco.Web/UmbracoApplication.cs +++ b/src/Umbraco.Web/UmbracoApplication.cs @@ -34,7 +34,10 @@ namespace Umbraco.Web var mainDom = new MainDom(loggerFactory.CreateLogger(), mainDomLock); - var requestCache = new HttpRequestAppCache(() => HttpContext.Current != null ? HttpContext.Current.Items : null); + // Commented out as part of .NET Core transition as the HttpRequestAppCache constructor has changed to + // to match the change in the type of the HTTP context Items collection. + //// var requestCache = new HttpRequestAppCache(() => HttpContext.Current != null ? HttpContext.Current.Items : null); + IRequestCache requestCache = null; var appCaches = new AppCaches( new DeepCloneAppCache(new ObjectCacheAppCache()), requestCache, diff --git a/src/Umbraco.Web/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs index 0be333d28c..baeab5634c 100644 --- a/src/Umbraco.Web/UmbracoApplicationBase.cs +++ b/src/Umbraco.Web/UmbracoApplicationBase.cs @@ -80,10 +80,7 @@ namespace Umbraco.Web return new VoidProfiler(); } - var webProfiler = new WebProfiler(); - webProfiler.Start(); - - return webProfiler; + return new VoidProfiler(); } protected UmbracoApplicationBase(ILogger logger, ILoggerFactory loggerFactory, SecuritySettings securitySettings, GlobalSettings globalSettings, ConnectionStrings connectionStrings, IIOHelper ioHelper, IProfiler profiler, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo)