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_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/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/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.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/EmailSender.cs b/src/Umbraco.Infrastructure/EmailSender.cs index 7964afb82f..6b83a3f3c7 100644 --- a/src/Umbraco.Infrastructure/EmailSender.cs +++ b/src/Umbraco.Infrastructure/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 @@ -41,7 +40,7 @@ namespace Umbraco.Core /// Sends the message non-async /// /// - public void Send(MailMessage message) + public void Send(EmailMessage message) { if (_smtpConfigured.Value == false && _enableEvents) { @@ -71,7 +70,7 @@ namespace Umbraco.Core /// /// /// - public async Task SendAsync(MailMessage message) + public async Task SendAsync(EmailMessage message) { if (_smtpConfigured.Value == false && _enableEvents) { @@ -131,9 +130,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; @@ -143,7 +142,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.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs b/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs index ba8dfd300f..1d829d998a 100644 --- a/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs +++ b/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs @@ -1,11 +1,11 @@ using System; -using System.Net.Mail; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Options; using Umbraco.Core; using Umbraco.Core.Configuration.Models; using Umbraco.Core.HealthCheck; +using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Infrastructure.HealthCheck; @@ -70,23 +70,20 @@ namespace Umbraco.Web.HealthCheck.NotificationMethods var subject = _textService.Localize("healthcheck/scheduledHealthCheckEmailSubject", new[] { host.ToString() }); - using (var mailMessage = CreateMailMessage(subject, message)) - { - await _emailSender.SendAsync(mailMessage); - } + + var mailMessage = CreateMailMessage(subject, message); + await _emailSender.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/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/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.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.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.Integration/Logging/LogviewerTests.cs b/src/Umbraco.Tests.Integration/Logging/LogviewerTests.cs index fd861eca2e..789fd24291 100644 --- a/src/Umbraco.Tests.Integration/Logging/LogviewerTests.cs +++ b/src/Umbraco.Tests.Integration/Logging/LogviewerTests.cs @@ -10,7 +10,7 @@ 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 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 037dab5d9e..8017dd617c 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; @@ -134,7 +135,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 ab1d577563..c35a166fb7 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -34,6 +34,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; @@ -50,14 +51,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(); @@ -127,16 +120,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(); @@ -251,9 +241,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(), @@ -436,10 +428,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(); 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/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/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/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/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/Umbraco.Infrastructure/Persistence/Repositories/SimilarNodeNameTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/SimilarNodeNameTests.cs index 8d8bae2e61..747bb542cd 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/SimilarNodeNameTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/SimilarNodeNameTests.cs @@ -7,72 +7,184 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositor [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() + public void Name_Is_Suffixed() { 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)" }, + new SimilarNodeName { Id = 1, Name = "Zulu" } }; - 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); + 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 (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)")] 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/Umbraco.Infrastructure/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/UserRepositoryTest.cs index b38d326b62..ba773716fd 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/UserRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/UserRepositoryTest.cs @@ -9,11 +9,13 @@ 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; @@ -24,6 +26,11 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositor [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.Integration.Umbraco.Infrastructure.Persistence.Repositor } } + [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/Umbraco.Infrastructure/Services/ContentTypeServiceVariantsTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentTypeServiceVariantsTests.cs index 7552ff4c41..d11210c093 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentTypeServiceVariantsTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentTypeServiceVariantsTests.cs @@ -15,7 +15,7 @@ using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; using Umbraco.Web.PublishedCache; -namespace Umbraco.Tests.Services +namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services { [TestFixture] [Apartment(ApartmentState.STA)] diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ThreadSafetyServiceTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ThreadSafetyServiceTest.cs index 7425cd8d2d..c36968adeb 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ThreadSafetyServiceTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ThreadSafetyServiceTest.cs @@ -15,7 +15,7 @@ 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 // 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 cf535d8f82..f8faeb9b6f 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs @@ -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 f427bd9a7b..c5629aca10 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/NavigableNavigatorTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/NavigableNavigatorTests.cs @@ -11,7 +11,7 @@ using Umbraco.Core.Xml; using Umbraco.Core.Xml.XPath; using NUnit.Framework; -namespace Umbraco.Tests.CoreXml +namespace Umbraco.Tests.UnitTests.Umbraco.Core.CoreXml { [TestFixture] public class NavigableNavigatorTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/RenamedRootNavigatorTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/RenamedRootNavigatorTests.cs index c904f7fbf9..5afc68955d 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/RenamedRootNavigatorTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/CoreXml/RenamedRootNavigatorTests.cs @@ -4,7 +4,7 @@ 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 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.Core/Packaging/PackageExtractionTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Packaging/PackageExtractionTests.cs index 140173282c..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 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 17e528fb05..387d8aff44 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/HealthChecks/HealthCheckResultsTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/HealthChecks/HealthCheckResultsTests.cs @@ -6,7 +6,7 @@ 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 diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DataTypeTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DataTypeTests.cs index d5c5ab7fd1..b94effb907 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DataTypeTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/DataTypeTests.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.Infrastucture.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models { [TestFixture] public class DataTypeTests diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PathValidationTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PathValidationTests.cs index a557bdf64f..117b9d87cc 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PathValidationTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Models/PathValidationTests.cs @@ -7,7 +7,7 @@ using Umbraco.Core.Models.Entities; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; -namespace Umbraco.Tests.UnitTests.Umbraco.Infrastucture.Models +namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models { [TestFixture] public class PathValidationTests 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.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 3740f83168..6126ee9419 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/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 afa74ed213..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 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.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 b8c49456c0..e9fef92a3c 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/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 24abe3f774..526e1aa252 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -130,16 +130,13 @@ - - - @@ -147,8 +144,8 @@ + - @@ -165,15 +162,12 @@ - - - @@ -184,9 +178,7 @@ - - @@ -200,17 +192,13 @@ - - - - @@ -219,9 +207,6 @@ - - - @@ -232,30 +217,17 @@ - - - - - - - - - - - - - @@ -266,14 +238,8 @@ - - - - - - @@ -283,28 +249,10 @@ - - - - - - - - - - - - - - - - - - @@ -313,7 +261,6 @@ ImportResources.resx - @@ -456,4 +403,4 @@ - + \ No newline at end of file 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 43dfad102d..0ea7dd67b7 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; @@ -345,6 +344,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); @@ -357,13 +357,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); @@ -405,6 +399,7 @@ namespace Umbraco.Web.BackOffice.Controllers return NotFound(); } + var from = _globalSettings.Smtp.From; // Generate the token and send it var code = await _userManager.GenerateTwoFactorTokenAsync(user, provider); if (string.IsNullOrWhiteSpace(code)) @@ -424,13 +419,7 @@ namespace Umbraco.Web.BackOffice.Controllers if (provider == "Email") { - 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 46c5625ee1..4ab5f9a969 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; @@ -34,6 +34,7 @@ using System.Security.Claims; 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 874cb6fe1d..62d26f1e25 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs @@ -18,7 +18,8 @@ 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 0026cc9bed..762e92b003 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 3e92747c21..533eab3cb1 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 95baeb489b..dc63a88109 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 defdd9f9df..1a8b1341d8 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 0d77eedd47..097b5a3310 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 f0c5702298..4cba5064d1 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 25c6d712c5..6a79040154 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 8a4346c2ac..cabc865d40 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 9ef5093ff3..679fcdad6b 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 b2a6ab099e..d5df536dae 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/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 2a05e0fbd9..755acdf0cb 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 c472ddd141..36b9f7f5de 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 7d001a8d90..ab332e3843 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 8d349172fd..31ab66908c 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/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 3c2da057f7..113f411c6f 100644 --- a/src/Umbraco.Web.Common/ModelBinders/ContentModelBinder.cs +++ b/src/Umbraco.Web.Common/ModelBinders/ContentModelBinder.cs @@ -56,7 +56,7 @@ 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 83b8e5b218..62954e4dc6 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.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 0889a9c019..5a190a90a5 100644 --- a/src/Umbraco.Web/Composing/Current.cs +++ b/src/Umbraco.Web/Composing/Current.cs @@ -167,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(); @@ -216,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(); @@ -264,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/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 e64f03f358..fda645065a 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 ea9a05b6d4..7f812b6e24 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 @@ - @@ -259,7 +244,6 @@ - @@ -332,11 +316,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)