Merge remote-tracking branch 'origin/temp8' into temp8-removes-config-based-indexes-3901

This commit is contained in:
Stephan
2019-01-10 14:04:52 +01:00
230 changed files with 1345 additions and 3273 deletions

View File

@@ -22,11 +22,11 @@
not want this to happen as the alpha of the next major is, really, the next major already.
-->
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.2.3, 2.999999)" />
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.0-alpha.26]" />
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.0-alpha.31]" />
<dependency id="ImageProcessor.Web" version="[4.9.3.25,4.999999)" />
<dependency id="ImageProcessor.Web.Config" version="[2.4.1.19,2.999999)" />
<dependency id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="[2.0.0,2.999999)" />
<dependency id="Microsoft.Net.Compilers" version="[2.9.0,2.999999)" />
<dependency id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="[2.0.1,2.999999)" />
<dependency id="Microsoft.Net.Compilers" version="[2.10.0,2.999999)" />
</dependencies>
</metadata>
<files>

View File

@@ -452,9 +452,22 @@
if ($this.OnError()) { return }
$this.PrepareAzureGallery()
if ($this.OnError()) { return }
$this.PostPackageHook()
if ($this.OnError()) { return }
Write-Host "Done"
})
$ubuild.DefineMethod("PostPackageHook",
{
# run hook
if ($this.HasMethod("PostPackage"))
{
Write-Host "Run PostPackage hook"
$this.PostPackage();
if (-not $?) { throw "Failed to run hook." }
}
})
# ################################################################
# RUN
# ################################################################

View File

@@ -19,4 +19,4 @@ using System.Resources;
// these are FYI and changed automatically
[assembly: AssemblyFileVersion("8.0.0")]
[assembly: AssemblyInformationalVersion("8.0.0-alpha.56")]
[assembly: AssemblyInformationalVersion("8.0.0-alpha.58")]

View File

@@ -23,7 +23,10 @@ namespace Umbraco.Core.Components
_auditService = auditService;
_userService = userService;
_entityService = entityService;
}
public void Initialize()
{
UserService.SavedUserGroup += OnSavedUserGroupWithUsers;
UserService.SavedUser += OnSavedUser;
@@ -37,6 +40,9 @@ namespace Umbraco.Core.Components
MemberService.Exported += OnMemberExported;
}
public void Terminate()
{ }
private IUser CurrentPerformingUser
{
get

View File

@@ -20,6 +20,21 @@ namespace Umbraco.Core.Components
_logger = logger;
}
public void Initialize()
{
using (_logger.DebugDuration<ComponentCollection>($"Initializing. (log components when >{LogThresholdMilliseconds}ms)", "Initialized."))
{
foreach (var component in this.Reverse()) // terminate components in reverse order
{
var componentType = component.GetType();
using (_logger.DebugDuration<ComponentCollection>($"Initializing {componentType.FullName}.", $"Initialized {componentType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
{
component.Initialize();
}
}
}
}
public void Terminate()
{
using (_logger.DebugDuration<ComponentCollection>($"Terminating. (log components when >{LogThresholdMilliseconds}ms)", "Terminated."))
@@ -29,6 +44,7 @@ namespace Umbraco.Core.Components
var componentType = component.GetType();
using (_logger.DebugDuration<ComponentCollection>($"Terminating {componentType.FullName}.", $"Terminated {componentType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
{
component.Terminate();
component.DisposeIfDisposable();
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Components
@@ -26,12 +27,21 @@ namespace Umbraco.Core.Components
/// <param name="typeLoader">A type loader.</param>
/// <param name="logger">A logger.</param>
/// <param name="runtimeState">The runtime state.</param>
public Composition(IRegister register, TypeLoader typeLoader, IProfilingLogger logger, IRuntimeState runtimeState)
/// <param name="configs">Optional configs.</param>
public Composition(IRegister register, TypeLoader typeLoader, IProfilingLogger logger, IRuntimeState runtimeState, Configs configs = null)
{
_register = register;
TypeLoader = typeLoader;
Logger = logger;
RuntimeState = runtimeState;
if (configs == null)
{
configs = new Configs();
configs.AddCoreConfigs();
}
Configs = configs;
}
#region Services
@@ -51,6 +61,11 @@ namespace Umbraco.Core.Components
/// </summary>
public IRuntimeState RuntimeState { get; }
/// <summary>
/// Gets the configurations.
/// </summary>
public Configs Configs { get; }
#endregion
#region IRegister
@@ -94,6 +109,8 @@ namespace Umbraco.Core.Components
foreach (var builder in _builders.Values)
builder.RegisterWith(_register);
Configs.RegisterWith(_register);
return _register.CreateFactory();
}

View File

@@ -5,11 +5,21 @@
/// </summary>
/// <remarks>
/// <para>Components are created by DI and therefore must have a public constructor.</para>
/// <para>All components which are also disposable, will be disposed in reverse
/// order, when Umbraco terminates.</para>
/// <para>All components are terminated in reverse order when Umbraco terminates, and
/// disposable components are disposed.</para>
/// <para>The Dispose method may be invoked more than once, and components
/// should ensure they support this.</para>
/// </remarks>
public interface IComponent
{ }
{
/// <summary>
/// Initializes the component.
/// </summary>
void Initialize();
/// <summary>
/// Terminates the component.
/// </summary>
void Terminate();
}
}

View File

@@ -1,20 +1,28 @@
using System;
using System.IO;
using System.IO;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Manifest;
namespace Umbraco.Core.Components
{
public sealed class ManifestWatcherComponent : IComponent, IDisposable
public sealed class ManifestWatcherComponent : IComponent
{
private readonly IRuntimeState _runtimeState;
private readonly ILogger _logger;
// if configured and in debug mode, a ManifestWatcher watches App_Plugins folders for
// package.manifest chances and restarts the application on any change
private ManifestWatcher _mw;
public ManifestWatcherComponent(IRuntimeState runtimeState, ILogger logger)
{
if (runtimeState.Debug == false) return;
_runtimeState = runtimeState;
_logger = logger;
}
public void Initialize()
{
if (_runtimeState.Debug == false) return;
//if (ApplicationContext.Current.IsConfigured == false || GlobalSettings.DebugMode == false)
// return;
@@ -22,11 +30,11 @@ namespace Umbraco.Core.Components
var appPlugins = IOHelper.MapPath("~/App_Plugins/");
if (Directory.Exists(appPlugins) == false) return;
_mw = new ManifestWatcher(logger);
_mw = new ManifestWatcher(_logger);
_mw.Start(Directory.GetDirectories(appPlugins));
}
public void Dispose()
public void Terminate()
{
if (_mw == null) return;

View File

@@ -8,11 +8,14 @@ namespace Umbraco.Core.Components
//TODO: This should just exist in the content service/repo!
public sealed class RelateOnCopyComponent : IComponent
{
public RelateOnCopyComponent()
public void Initialize()
{
ContentService.Copied += ContentServiceCopied;
}
public void Terminate()
{ }
private static void ContentServiceCopied(IContentService sender, Events.CopyEventArgs<IContent> e)
{
if (e.RelateToOriginal == false) return;

View File

@@ -9,7 +9,7 @@ namespace Umbraco.Core.Components
{
public sealed class RelateOnTrashComponent : IComponent
{
public RelateOnTrashComponent()
public void Initialize()
{
ContentService.Moved += ContentService_Moved;
ContentService.Trashed += ContentService_Trashed;
@@ -17,6 +17,9 @@ namespace Umbraco.Core.Components
MediaService.Trashed += MediaService_Trashed;
}
public void Terminate()
{ }
private static void ContentService_Moved(IContentService sender, MoveEventArgs<IContent> e)
{
foreach (var item in e.MoveInfoCollection.Where(x => x.OriginalPath.Contains(Constants.System.RecycleBinContent.ToInvariantString())))

View File

@@ -5,24 +5,19 @@ using Umbraco.Core.Configuration.UmbracoSettings;
namespace Umbraco.Core.Composing.Composers
{
/// <summary>
/// Sets up IoC container for Umbraco configuration classes
/// Compose configurations.
/// </summary>
public static class ConfigurationComposer
{
public static Composition ComposeConfiguration(this Composition composition)
{
composition.RegisterUnique<UmbracoConfig>();
composition.RegisterUnique(factory => factory.GetInstance<UmbracoConfig>().Umbraco());
// common configurations are already registered
// register others
composition.RegisterUnique(factory => factory.GetInstance<IUmbracoSettingsSection>().Content);
composition.RegisterUnique(factory => factory.GetInstance<IUmbracoSettingsSection>().Templates);
composition.RegisterUnique(factory => factory.GetInstance<IUmbracoSettingsSection>().RequestHandler);
composition.RegisterUnique(factory => factory.GetInstance<IUmbracoSettingsSection>().Security);
composition.RegisterUnique(factory => factory.GetInstance<UmbracoConfig>().Global());
composition.RegisterUnique(factory => factory.GetInstance<UmbracoConfig>().Dashboards());
composition.RegisterUnique(factory => factory.GetInstance<UmbracoConfig>().HealthChecks());
composition.RegisterUnique(factory => factory.GetInstance<UmbracoConfig>().Grids());
// fixme - other sections we need to add?
return composition;
}

View File

@@ -39,7 +39,7 @@ namespace Umbraco.Core.Composing
private static IProfiler _profiler;
private static IProfilingLogger _profilingLogger;
private static IPublishedValueFallback _publishedValueFallback;
private static UmbracoConfig _config;
private static Configs _configs;
/// <summary>
/// Gets or sets the factory.
@@ -48,25 +48,32 @@ namespace Umbraco.Core.Composing
{
get
{
if (_factory == null) throw new Exception("No factory has been set.");
if (_factory == null) throw new InvalidOperationException("No factory has been set.");
return _factory;
}
set
{
if (_factory != null) throw new Exception("A factory has already been set.");
if (_factory != null) throw new InvalidOperationException("A factory has already been set.");
if (_configs != null) throw new InvalidOperationException("Configs are unlocked.");
_factory = value;
}
}
internal static bool HasContainer => _factory != null;
internal static bool HasFactory => _factory != null;
// for UNIT TESTS exclusively!
// resets *everything* that is 'current'
internal static void Reset()
/// <summary>
/// Resets <see cref="Current"/>. Indented for testing only, and not supported in production code.
/// </summary>
/// <remarks>
/// <para>For UNIT TESTS exclusively.</para>
/// <para>Resets everything that is 'current'.</para>
/// </remarks>
public static void Reset()
{
_factory.DisposeIfDisposable();
_factory = null;
_configs = null;
_shortStringHelper = null;
_logger = null;
_profiler = null;
@@ -76,21 +83,36 @@ namespace Umbraco.Core.Composing
Resetted?.Invoke(null, EventArgs.Empty);
}
/// <summary>
/// Unlocks <see cref="Configs"/>. Intended for testing only, and not supported in production code.
/// </summary>
/// <remarks>
/// <para>For UNIT TESTS exclusively.</para>
/// <para>Unlocks <see cref="Configs"/> so that it is possible to add configurations
/// directly to <see cref="Current"/> without having to wire composition.</para>
/// </remarks>
public static void UnlockConfigs()
{
if (_factory != null)
throw new InvalidOperationException("Cannot unlock configs when a factory has been set.");
_configs = new Configs();
}
internal static event EventHandler Resetted;
#region Getters
public static IShortStringHelper ShortStringHelper
=> _shortStringHelper ?? (_shortStringHelper = _factory?.TryGetInstance<IShortStringHelper>()
?? new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(Config.Umbraco())));
?? new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(Configs.Settings())));
public static ILogger Logger
=> _logger ?? (_logger = _factory?.TryGetInstance<ILogger>()
?? new DebugDiagnosticsLogger());
?? new DebugDiagnosticsLogger());
public static IProfiler Profiler
=> _profiler ?? (_profiler = _factory?.TryGetInstance<IProfiler>()
?? new LogProfiler(Logger));
?? new LogProfiler(Logger));
public static IProfilingLogger ProfilingLogger
=> _profilingLogger ?? (_profilingLogger = _factory?.TryGetInstance<IProfilingLogger>())
@@ -102,9 +124,15 @@ namespace Umbraco.Core.Composing
public static TypeLoader TypeLoader
=> Factory.GetInstance<TypeLoader>();
public static UmbracoConfig Config
=> _config ?? (_config = _factory?.TryGetInstance<UmbracoConfig>()
?? new UmbracoConfig(Logger, _factory?.TryGetInstance<IRuntimeCacheProvider>(), _factory?.TryGetInstance<IRuntimeState>()));
public static Configs Configs
{
get
{
if (_configs != null) return _configs;
if (_factory == null) throw new InvalidOperationException("Can not get Current.Config during composition. Use composition.Config.");
return _factory.GetInstance<Configs>();
}
}
public static IFileSystems FileSystems
=> Factory.GetInstance<IFileSystems>();

View File

@@ -0,0 +1,52 @@
using System.IO;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Dashboard;
using Umbraco.Core.Configuration.Grid;
using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Core
{
/// <summary>
/// Provides extension methods for the <see cref="Configs"/> class.
/// </summary>
public static class ConfigsExtensions
{
public static IGlobalSettings Global(this Configs configs)
=> configs.GetConfig<IGlobalSettings>();
public static IUmbracoSettingsSection Settings(this Configs configs)
=> configs.GetConfig<IUmbracoSettingsSection>();
public static IDashboardSection Dashboards(this Configs configs)
=> configs.GetConfig<IDashboardSection>();
public static IHealthChecks HealthChecks(this Configs configs)
=> configs.GetConfig<IHealthChecks>();
public static IGridConfig Grids(this Configs configs)
=> configs.GetConfig<IGridConfig>();
internal static CoreDebug CoreDebug(this Configs configs)
=> configs.GetConfig<CoreDebug>();
public static void AddCoreConfigs(this Configs configs)
{
var configDir = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Config));
configs.Add<IGlobalSettings>(() => new GlobalSettings());
configs.Add<IUmbracoSettingsSection>("umbracoConfiguration/settings");
configs.Add<IDashboardSection>("umbracoConfiguration/dashBoard");
configs.Add<IHealthChecks>("umbracoConfiguration/HealthChecks");
configs.Add(() => new CoreDebug());
// GridConfig depends on runtime caches, manifest parsers... and cannot be available during composition
configs.Add<IGridConfig>(factory => new GridConfig(factory.GetInstance<ILogger>(), factory.GetInstance<IRuntimeCacheProvider>(), configDir, factory.GetInstance<IRuntimeState>().Debug));
}
}
}

View File

@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Configuration
{
/// <summary>
/// Represents Umbraco configurations.
/// </summary>
/// <remarks>
/// <para>During composition, use composition.Configs. When running, either inject the required configuration,
/// or use Current.Configs.</para>
/// </remarks>
public class Configs
{
private readonly Dictionary<Type, Lazy<object>> _configs = new Dictionary<Type, Lazy<object>>();
private Dictionary<Type, Action<IRegister>> _registerings = new Dictionary<Type, Action<IRegister>>();
/// <summary>
/// Gets a configuration.
/// </summary>
public TConfig GetConfig<TConfig>()
where TConfig : class
{
if (!_configs.TryGetValue(typeof(TConfig), out var configFactory))
throw new InvalidOperationException($"No configuration of type {typeof(TConfig)} has been added.");
return (TConfig) configFactory.Value;
}
/// <summary>
/// Adds a configuration, provided by a factory.
/// </summary>
public void Add<TConfig>(Func<TConfig> configFactory)
where TConfig : class
{
// make sure it is not too late
if (_registerings == null)
throw new InvalidOperationException("Configurations have already been registered.");
var typeOfConfig = typeof(TConfig);
var lazyConfigFactory = _configs[typeOfConfig] = new Lazy<object>(configFactory);
_registerings[typeOfConfig] = register => register.Register(_ => (TConfig) lazyConfigFactory.Value, Lifetime.Singleton);
}
/// <summary>
/// Adds a configuration, provided by a factory.
/// </summary>
public void Add<TConfig>(Func<IFactory, TConfig> configFactory)
where TConfig : class
{
// make sure it is not too late
if (_registerings == null)
throw new InvalidOperationException("Configurations have already been registered.");
var typeOfConfig = typeof(TConfig);
_configs[typeOfConfig] = new Lazy<object>(() =>
{
if (Current.HasFactory) return Current.Factory.GetInstance<TConfig>();
throw new InvalidOperationException($"Cannot get configuration of type {typeOfConfig} during composition.");
});
_registerings[typeOfConfig] = register => register.Register(configFactory, Lifetime.Singleton);
}
/// <summary>
/// Adds a configuration, provided by a configuration section.
/// </summary>
public void Add<TConfig>(string sectionName)
where TConfig : class
{
Add(() => GetConfig<TConfig>(sectionName));
}
private static TConfig GetConfig<TConfig>(string sectionName)
where TConfig : class
{
// note: need to use SafeCallContext here because ConfigurationManager.GetSection ends up getting AppDomain.Evidence
// which will want to serialize the call context including anything that is in there - what a mess!
using (new SafeCallContext())
{
if ((ConfigurationManager.GetSection(sectionName) is TConfig config))
return config;
var ex = new ConfigurationErrorsException($"Could not get configuration section \"{sectionName}\" from config files.");
Current.Logger.Error<Configs>(ex, "Config error");
throw ex;
}
}
/// <summary>
/// Registers configurations in a register.
/// </summary>
public void RegisterWith(IRegister register)
{
// do it only once
if (_registerings == null)
throw new InvalidOperationException("Configurations have already been registered.");
register.RegisterInstance(this);
foreach (var registering in _registerings.Values)
registering(register);
// no need to keep them around
_registerings = null;
}
}
}

View File

@@ -2,16 +2,6 @@
namespace Umbraco.Core.Configuration
{
internal static class CoreDebugExtensions
{
private static CoreDebug _coreDebug;
public static CoreDebug CoreDebug(this UmbracoConfig config)
{
return _coreDebug ?? (_coreDebug = new CoreDebug());
}
}
internal class CoreDebug
{
public CoreDebug()

View File

@@ -6,11 +6,11 @@ namespace Umbraco.Core.Configuration.Grid
{
class GridConfig : IGridConfig
{
public GridConfig(ILogger logger, IRuntimeCacheProvider runtimeCache, DirectoryInfo appPlugins, DirectoryInfo configFolder, bool isDebug)
public GridConfig(ILogger logger, IRuntimeCacheProvider runtimeCache, DirectoryInfo configFolder, bool isDebug)
{
EditorsConfig = new GridEditorsConfig(logger, runtimeCache, appPlugins, configFolder, isDebug);
EditorsConfig = new GridEditorsConfig(logger, runtimeCache, configFolder, isDebug);
}
public IGridEditorsConfig EditorsConfig { get; private set; }
public IGridEditorsConfig EditorsConfig { get; }
}
}

View File

@@ -14,15 +14,13 @@ namespace Umbraco.Core.Configuration.Grid
{
private readonly ILogger _logger;
private readonly IRuntimeCacheProvider _runtimeCache;
private readonly DirectoryInfo _appPlugins;
private readonly DirectoryInfo _configFolder;
private readonly bool _isDebug;
public GridEditorsConfig(ILogger logger, IRuntimeCacheProvider runtimeCache, DirectoryInfo appPlugins, DirectoryInfo configFolder, bool isDebug)
public GridEditorsConfig(ILogger logger, IRuntimeCacheProvider runtimeCache, DirectoryInfo configFolder, bool isDebug)
{
_logger = logger;
_runtimeCache = runtimeCache;
_appPlugins = appPlugins;
_configFolder = configFolder;
_isDebug = isDebug;
}
@@ -31,7 +29,7 @@ namespace Umbraco.Core.Configuration.Grid
{
get
{
Func<List<GridEditor>> getResult = () =>
List<GridEditor> GetResult()
{
// fixme - should use the common one somehow! + ignoring _appPlugins here!
var parser = new ManifestParser(_runtimeCache, Current.ManifestValidators, _logger);
@@ -55,20 +53,16 @@ namespace Umbraco.Core.Configuration.Grid
// add manifest editors, skip duplicates
foreach (var gridEditor in parser.Manifest.GridEditors)
{
if (editors.Contains(gridEditor) == false)
editors.Add(gridEditor);
if (editors.Contains(gridEditor) == false) editors.Add(gridEditor);
}
return editors;
};
}
//cache the result if debugging is disabled
var result = _isDebug
? getResult()
: _runtimeCache.GetCacheItem<List<GridEditor>>(
typeof(GridEditorsConfig) + "Editors",
() => getResult(),
TimeSpan.FromMinutes(10));
? GetResult()
: _runtimeCache.GetCacheItem<List<GridEditor>>(typeof(GridEditorsConfig) + ".Editors",GetResult, TimeSpan.FromMinutes(10));
return result;
}

View File

@@ -1,138 +0,0 @@
using System;
using System.Configuration;
using System.IO;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.Dashboard;
using Umbraco.Core.Configuration.Grid;
using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Composing;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Configuration
{
/// <summary>
/// The gateway to all umbraco configuration.
/// </summary>
/// <remarks>This should be registered as a unique service in the container.</remarks>
public class UmbracoConfig
{
private IGlobalSettings _global;
private Lazy<IUmbracoSettingsSection> _umbraco;
private Lazy<IHealthChecks> _healthChecks;
private Lazy<IDashboardSection> _dashboards;
private Lazy<IGridConfig> _grids;
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoConfig"/> class.
/// </summary>
public UmbracoConfig(ILogger logger, IRuntimeCacheProvider runtimeCache, IRuntimeState runtimeState)
{
_global = new GlobalSettings();
var appPluginsDir = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.AppPlugins));
var configDir = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Config));
_umbraco = new Lazy<IUmbracoSettingsSection>(() => GetConfig<IUmbracoSettingsSection>("umbracoConfiguration/settings"));
_dashboards = new Lazy<IDashboardSection>(() =>GetConfig<IDashboardSection>("umbracoConfiguration/dashBoard"));
_healthChecks = new Lazy<IHealthChecks>(() => GetConfig<IHealthChecks>("umbracoConfiguration/HealthChecks"));
_grids = new Lazy<IGridConfig>(() => new GridConfig(logger, runtimeCache, appPluginsDir, configDir, runtimeState.Debug));
}
/// <summary>
/// Gets a typed and named config section.
/// </summary>
/// <typeparam name="TConfig">The type of the configuration section.</typeparam>
/// <param name="sectionName">The name of the configuration section.</param>
/// <returns>The configuration section.</returns>
public static TConfig GetConfig<TConfig>(string sectionName)
where TConfig : class
{
// note: need to use SafeCallContext here because ConfigurationManager.GetSection ends up getting AppDomain.Evidence
// which will want to serialize the call context including anything that is in there - what a mess!
using (new SafeCallContext())
{
if ((ConfigurationManager.GetSection(sectionName) is TConfig config))
return config;
var ex = new ConfigurationErrorsException($"Could not get configuration section \"{sectionName}\" from config files.");
Current.Logger.Error<UmbracoConfig>(ex, "Config error");
throw ex;
}
}
/// <summary>
/// Gets the global configuration.
/// </summary>
public IGlobalSettings Global()
=> _global;
/// <summary>
/// Gets the Umbraco configuration.
/// </summary>
public IUmbracoSettingsSection Umbraco()
=> _umbraco.Value;
/// <summary>
/// Gets the dashboards configuration.
/// </summary>
public IDashboardSection Dashboards()
=> _dashboards.Value;
/// <summary>
/// Gets the health checks configuration.
/// </summary>
public IHealthChecks HealthChecks()
=> _healthChecks.Value;
/// <summary>
/// Gets the grids configuration.
/// </summary>
public IGridConfig Grids()
=> _grids.Value;
/// <summary>
/// Sets the global configuration, for tests only.
/// </summary>
public void SetGlobalConfig(IGlobalSettings value)
{
_global = value;
}
/// <summary>
/// Sets the Umbraco configuration, for tests only.
/// </summary>
public void SetUmbracoConfig(IUmbracoSettingsSection value)
{
_umbraco = new Lazy<IUmbracoSettingsSection>(() => value);
}
/// <summary>
/// Sets the dashboards configuration, for tests only.
/// </summary>
/// <param name="value"></param>
public void SetDashboardsConfig(IDashboardSection value)
{
_dashboards = new Lazy<IDashboardSection>(() => value);
}
/// <summary>
/// Sets the health checks configuration, for tests only.
/// </summary>
public void SetHealthChecksConfig(IHealthChecks value)
{
_healthChecks = new Lazy<IHealthChecks>(() => value);
}
/// <summary>
/// Sets the grids configuration, for tests only.
/// </summary>
public void SetGridsConfig(IGridConfig value)
{
_grids = new Lazy<IGridConfig>(() => value);
}
//TODO: Add other configurations here !
}
}

View File

@@ -65,5 +65,33 @@ namespace Umbraco.Core.IO
}
fs.DeleteFile(tempFile);
}
/// <summary>
/// Unwraps a filesystem.
/// </summary>
/// <remarks>
/// <para>A filesystem can be wrapped in a <see cref="FileSystemWrapper"/> (public) or a <see cref="ShadowWrapper"/> (internal),
/// and this method deals with the various wrappers and </para>
/// </remarks>
public static IFileSystem Unwrap(this IFileSystem filesystem)
{
var unwrapping = true;
while (unwrapping)
{
switch (filesystem)
{
case FileSystemWrapper wrapper:
filesystem = wrapper.InnerFileSystem;
break;
case ShadowWrapper shadow:
filesystem = shadow.InnerFileSystem;
break;
default:
unwrapping = false;
break;
}
}
return filesystem;
}
}
}

View File

@@ -21,7 +21,7 @@ namespace Umbraco.Core.IO
InnerFileSystem = innerFileSystem;
}
public IFileSystem InnerFileSystem { get; internal set; }
internal IFileSystem InnerFileSystem { get; set; }
public IEnumerable<string> GetDirectories(string path)
{

View File

@@ -31,7 +31,7 @@ namespace Umbraco.Core.IO.MediaPathSchemes
// prevpath should be "<int>/<filename>" OR "<int>-<filename>"
// and we want to reuse the "<int>" part, so try to find it
var sep = Current.Config.Umbraco().Content.UploadAllowDirectories ? "/" : "-";
var sep = Current.Configs.Settings().Content.UploadAllowDirectories ? "/" : "-";
var pos = previous.IndexOf(sep, StringComparison.Ordinal);
var s = pos > 0 ? previous.Substring(0, pos) : null;
@@ -45,7 +45,7 @@ namespace Umbraco.Core.IO.MediaPathSchemes
if (directory == null)
throw new InvalidOperationException("Cannot use a null directory.");
return Current.Config.Umbraco().Content.UploadAllowDirectories
return Current.Configs.Settings().Content.UploadAllowDirectories
? Path.Combine(directory, filename).Replace('\\', '/')
: directory + "-" + filename;
}

View File

@@ -75,6 +75,8 @@ namespace Umbraco.Core.IO
}
}
public IFileSystem InnerFileSystem => _innerFileSystem;
private IFileSystem FileSystem
{
get

View File

@@ -166,7 +166,7 @@ namespace Umbraco.Core.Logging.Serilog
messageTemplate += "\r\nThe thread has been aborted, because the request has timed out.";
// dump if configured, or if stacktrace contains Monitor.ReliableEnter
dump = Current.Config.CoreDebug().DumpOnTimeoutThreadAbort || IsMonitorEnterThreadAbortException(exception);
dump = Current.Configs.CoreDebug().DumpOnTimeoutThreadAbort || IsMonitorEnterThreadAbortException(exception);
// dump if it is ok to dump (might have a cap on number of dump...)
dump &= MiniDump.OkToDump();
@@ -217,9 +217,9 @@ namespace Umbraco.Core.Logging.Serilog
/// <inheritdoc/>
public void Warn(Type reporting, string message)
{
LoggerFor(reporting).Warning(message);
LoggerFor(reporting).Warning(message);
}
/// <inheritdoc/>
public void Warn(Type reporting, string message, params object[] propertyValues)
{
@@ -231,7 +231,7 @@ namespace Umbraco.Core.Logging.Serilog
{
LoggerFor(reporting).Warning(exception, message);
}
/// <inheritdoc/>
public void Warn(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues)
{
@@ -255,7 +255,7 @@ namespace Umbraco.Core.Logging.Serilog
{
LoggerFor(reporting).Debug(message);
}
/// <inheritdoc/>
public void Debug(Type reporting, string messageTemplate, params object[] propertyValues)
{

View File

@@ -67,7 +67,7 @@ namespace Umbraco.Core.Models.Identity
_startContentIds = new int[] { };
_groups = new IReadOnlyUserGroup[] { };
_allowedSections = new string[] { };
_culture = Current.Config.Global().DefaultUILanguage; //fixme inject somehow?
_culture = Current.Configs.Global().DefaultUILanguage; //fixme inject somehow?
_groups = new IReadOnlyUserGroup[0];
_roles = new ObservableCollection<IdentityUserRole<string>>();
_roles.CollectionChanged += _roles_CollectionChanged;
@@ -84,7 +84,7 @@ namespace Umbraco.Core.Models.Identity
_startContentIds = new int[] { };
_groups = new IReadOnlyUserGroup[] { };
_allowedSections = new string[] { };
_culture = Current.Config.Global().DefaultUILanguage; //fixme inject somehow?
_culture = Current.Configs.Global().DefaultUILanguage; //fixme inject somehow?
_groups = groups.ToArray();
_roles = new ObservableCollection<IdentityUserRole<string>>(_groups.Select(x => new IdentityUserRole<string>
{

View File

@@ -27,7 +27,7 @@ namespace Umbraco.Core.Models.Membership
{
SessionTimeout = 60;
_userGroups = new HashSet<IReadOnlyUserGroup>();
_language = Current.Config.Global().DefaultUILanguage; //fixme inject somehow?
_language = Current.Configs.Global().DefaultUILanguage; //fixme inject somehow?
_isApproved = true;
_isLockedOut = false;
_startContentIds = new int[] { };

View File

@@ -21,7 +21,7 @@ namespace Umbraco.Core.Models.PublishedContent
// in order to provide a nice, "fluent" experience, this extension method
// needs to access Current, which is not always initialized in tests - not
// very elegant, but works
if (!Current.HasContainer) return content;
if (!Current.HasFactory) return content;
// get model
// if factory returns nothing, throw

View File

@@ -93,18 +93,36 @@ namespace Umbraco.Core.Persistence.Factories
return dto;
}
public static IEnumerable<PropertyDataDto> BuildDtos(int currentVersionId, int publishedVersionId, IEnumerable<Property> properties, ILanguageRepository languageRepository, out bool edited, out HashSet<string> editedCultures)
/// <summary>
/// Creates a collection of <see cref="PropertyDataDto"/> from a collection of <see cref="Property"/>
/// </summary>
/// <param name="contentVariation">
/// The <see cref="ContentVariation"/> of the entity containing the collection of <see cref="Property"/>
/// </param>
/// <param name="currentVersionId"></param>
/// <param name="publishedVersionId"></param>
/// <param name="properties">The properties to map</param>
/// <param name="languageRepository"></param>
/// <param name="edited">out parameter indicating that one or more properties have been edited</param>
/// <param name="editedCultures">out parameter containing a collection of of edited cultures when the contentVariation varies by culture</param>
/// <returns></returns>
public static IEnumerable<PropertyDataDto> BuildDtos(ContentVariation contentVariation, int currentVersionId, int publishedVersionId, IEnumerable<Property> properties,
ILanguageRepository languageRepository, out bool edited, out HashSet<string> editedCultures)
{
var propertyDataDtos = new List<PropertyDataDto>();
edited = false;
editedCultures = null; // don't allocate unless necessary
string defaultCulture = null; //don't allocate unless necessary
var entityVariesByCulture = contentVariation.VariesByCulture();
foreach (var property in properties)
{
if (property.PropertyType.IsPublishing)
{
var editingCultures = property.PropertyType.VariesByCulture();
if (editingCultures && editedCultures == null) editedCultures = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
//create the resulting hashset if it's not created and the entity varies by culture
if (entityVariesByCulture && editedCultures == null)
editedCultures = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
// publishing = deal with edit and published values
foreach (var propertyValue in property.Values)
@@ -125,12 +143,24 @@ namespace Umbraco.Core.Persistence.Factories
var sameValues = propertyValue.PublishedValue == null ? propertyValue.EditedValue == null : propertyValue.PublishedValue.Equals(propertyValue.EditedValue);
edited |= !sameValues;
if (editingCultures && // cultures can be edited, ie CultureNeutral is supported
propertyValue.Culture != null && propertyValue.Segment == null && // and value is CultureNeutral
!sameValues) // and edited and published are different
if (entityVariesByCulture // cultures can be edited, ie CultureNeutral is supported
&& propertyValue.Culture != null && propertyValue.Segment == null // and value is CultureNeutral
&& !sameValues) // and edited and published are different
{
editedCultures.Add(propertyValue.Culture); // report culture as edited
}
// flag culture as edited if it contains an edited invariant property
if (propertyValue.Culture == null //invariant property
&& !sameValues // and edited and published are different
&& entityVariesByCulture) //only when the entity is variant
{
if (defaultCulture == null)
defaultCulture = languageRepository.GetDefaultIsoCode();
editedCultures.Add(defaultCulture);
}
}
}
else

View File

@@ -352,7 +352,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
}
// persist the property data
var propertyDataDtos = PropertyFactory.BuildDtos(content.VersionId, content.PublishedVersionId, entity.Properties, LanguageRepository, out var edited, out var editedCultures);
var propertyDataDtos = PropertyFactory.BuildDtos(content.ContentType.Variations, content.VersionId, content.PublishedVersionId, entity.Properties, LanguageRepository, out var edited, out var editedCultures);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);
@@ -527,7 +527,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
Database.Execute(deletePropertyDataSql);
// insert property data
var propertyDataDtos = PropertyFactory.BuildDtos(content.VersionId, publishing ? content.PublishedVersionId : 0, entity.Properties, LanguageRepository, out var edited, out var editedCultures);
var propertyDataDtos = PropertyFactory.BuildDtos(content.ContentType.Variations, content.VersionId, publishing ? content.PublishedVersionId : 0,
entity.Properties, LanguageRepository, out var edited, out var editedCultures);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);

View File

@@ -284,7 +284,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
Database.Insert(mediaVersionDto);
// persist the property data
var propertyDataDtos = PropertyFactory.BuildDtos(media.VersionId, 0, entity.Properties, LanguageRepository, out _, out _);
var propertyDataDtos = PropertyFactory.BuildDtos(media.ContentType.Variations, media.VersionId, 0, entity.Properties, LanguageRepository, out _, out _);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);
@@ -341,7 +341,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
// replace the property data
var deletePropertyDataSql = SqlContext.Sql().Delete<PropertyDataDto>().Where<PropertyDataDto>(x => x.VersionId == media.VersionId);
Database.Execute(deletePropertyDataSql);
var propertyDataDtos = PropertyFactory.BuildDtos(media.VersionId, 0, entity.Properties, LanguageRepository, out _, out _);
var propertyDataDtos = PropertyFactory.BuildDtos(media.ContentType.Variations, media.VersionId, 0, entity.Properties, LanguageRepository, out _, out _);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);

View File

@@ -310,7 +310,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
Database.Insert(dto);
// persist the property data
var propertyDataDtos = PropertyFactory.BuildDtos(member.VersionId, 0, entity.Properties, LanguageRepository, out _, out _);
var propertyDataDtos = PropertyFactory.BuildDtos(member.ContentType.Variations, member.VersionId, 0, entity.Properties, LanguageRepository, out _, out _);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);
@@ -375,7 +375,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
// replace the property data
var deletePropertyDataSql = SqlContext.Sql().Delete<PropertyDataDto>().Where<PropertyDataDto>(x => x.VersionId == member.VersionId);
Database.Execute(deletePropertyDataSql);
var propertyDataDtos = PropertyFactory.BuildDtos(member.VersionId, 0, entity.Properties, LanguageRepository, out _, out _);
var propertyDataDtos = PropertyFactory.BuildDtos(member.ContentType.Variations, member.VersionId, 0, entity.Properties, LanguageRepository, out _, out _);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
@@ -106,16 +107,18 @@ namespace Umbraco.Core.Runtime
// database factory
var databaseFactory = GetDatabaseFactory();
// configs
var configs = GetConfigs();
// type loader
var globalSettings = Current.Config.Global();
var localTempStorage = globalSettings.LocalTempStorageLocation;
var localTempStorage = configs.Global().LocalTempStorageLocation;
var typeLoader = new TypeLoader(runtimeCache, localTempStorage, ProfilingLogger);
// runtime state
// beware! must use '() => _factory.GetInstance<T>()' and NOT '_factory.GetInstance<T>'
// as the second one captures the current value (null) and therefore fails
_state = new RuntimeState(Logger,
Current.Config.Umbraco(), Current.Config.Global(),
configs.Settings(), configs.Global(),
new Lazy<IMainDom>(() => _factory.GetInstance<IMainDom>()),
new Lazy<IServerRegistrar>(() => _factory.GetInstance<IServerRegistrar>()))
{
@@ -126,7 +129,7 @@ namespace Umbraco.Core.Runtime
var mainDom = new MainDom(Logger);
// create the composition
composition = new Composition(register, typeLoader, ProfilingLogger, _state);
composition = new Composition(register, typeLoader, ProfilingLogger, _state, configs);
composition.RegisterEssentials(Logger, Profiler, ProfilingLogger, mainDom, appCaches, databaseFactory, typeLoader, _state);
// register runtime-level services
@@ -146,14 +149,20 @@ namespace Umbraco.Core.Runtime
// create the factory
_factory = Current.Factory = composition.CreateFactory();
// create the components
// create & initialize the components
_components = _factory.GetInstance<ComponentCollection>();
_components.Initialize();
}
catch (Exception e)
{
_state.Level = RuntimeLevel.BootFailed;
var bfe = e as BootFailedException ?? new BootFailedException("Boot failed.", e);
_state.BootFailedException = bfe;
if (_state != null)
{
_state.Level = RuntimeLevel.BootFailed;
_state.BootFailedException = bfe;
}
timer.Fail(exception: bfe); // be sure to log the exception - even if we repeat ourselves
// if something goes wrong above, we may end up with no factory
@@ -168,6 +177,8 @@ namespace Umbraco.Core.Runtime
catch { /* yea */ }
}
Debugger.Break();
// throwing here can cause w3wp to hard-crash and we want to avoid it.
// instead, we're logging the exception and setting level to BootFailed.
// various parts of Umbraco such as UmbracoModule and UmbracoDefaultOwinStartup
@@ -338,6 +349,16 @@ namespace Umbraco.Core.Runtime
protected internal virtual IUmbracoDatabaseFactory GetDatabaseFactory()
=> new UmbracoDatabaseFactory(Logger, new Lazy<IMapperCollection>(() => _factory.GetInstance<IMapperCollection>()));
/// <summary>
/// Gets the configurations.
/// </summary>
protected virtual Configs GetConfigs()
{
var configs = new Configs();
configs.AddCoreConfigs();
return configs;
}
#endregion
}
}

View File

@@ -7,12 +7,19 @@ namespace Umbraco.Core.Runtime
{
public class CoreRuntimeComponent : IComponent
{
private readonly IEnumerable<Profile> _mapperProfiles;
public CoreRuntimeComponent(IEnumerable<Profile> mapperProfiles)
{
_mapperProfiles = mapperProfiles;
}
public void Initialize()
{
// mapper profiles have been registered & are created by the container
Mapper.Initialize(configuration =>
{
foreach (var profile in mapperProfiles)
foreach (var profile in _mapperProfiles)
configuration.AddProfile(profile);
});
@@ -24,5 +31,8 @@ namespace Umbraco.Core.Runtime
IOHelper.EnsurePathExists(SystemDirectories.MvcViews + "/Partials");
IOHelper.EnsurePathExists(SystemDirectories.MvcViews + "/MacroPartials");
}
public void Terminate()
{ }
}
}

View File

@@ -492,7 +492,7 @@ namespace Umbraco.Core.Scoping
// caching config
// true if Umbraco.CoreDebug.LogUncompletedScope appSetting is set to "true"
private static bool LogUncompletedScopes => (_logUncompletedScopes
?? (_logUncompletedScopes = Current.Config.CoreDebug().LogUncompletedScopes)).Value;
?? (_logUncompletedScopes = Current.Configs.CoreDebug().LogUncompletedScopes)).Value;
/// <inheritdoc />
public void ReadLock(params int[] lockIds)

View File

@@ -88,11 +88,11 @@ namespace Umbraco.Core.Security
/// <returns></returns>
public static MembershipProvider GetUsersMembershipProvider()
{
if (Membership.Providers[Current.Config.Umbraco().Providers.DefaultBackOfficeUserProvider] == null)
if (Membership.Providers[Current.Configs.Settings().Providers.DefaultBackOfficeUserProvider] == null)
{
throw new InvalidOperationException("No membership provider found with name " + Current.Config.Umbraco().Providers.DefaultBackOfficeUserProvider);
throw new InvalidOperationException("No membership provider found with name " + Current.Configs.Settings().Providers.DefaultBackOfficeUserProvider);
}
return Membership.Providers[Current.Config.Umbraco().Providers.DefaultBackOfficeUserProvider];
return Membership.Providers[Current.Configs.Settings().Providers.DefaultBackOfficeUserProvider];
}
/// <summary>

View File

@@ -1114,7 +1114,7 @@ namespace Umbraco.Core
/// <remarks>Checks <c>UmbracoSettings.ForceSafeAliases</c> to determine whether it should filter the text.</remarks>
public static string ToSafeAliasWithForcingCheck(this string alias)
{
return Current.Config.Umbraco().Content.ForceSafeAliases ? alias.ToSafeAlias() : alias;
return Current.Configs.Settings().Content.ForceSafeAliases ? alias.ToSafeAlias() : alias;
}
/// <summary>
@@ -1126,7 +1126,7 @@ namespace Umbraco.Core
/// <remarks>Checks <c>UmbracoSettings.ForceSafeAliases</c> to determine whether it should filter the text.</remarks>
public static string ToSafeAliasWithForcingCheck(this string alias, string culture)
{
return Current.Config.Umbraco().Content.ForceSafeAliases ? alias.ToSafeAlias(culture) : alias;
return Current.Configs.Settings().Content.ForceSafeAliases ? alias.ToSafeAlias(culture) : alias;
}
// the new methods to get a url segment

View File

@@ -204,6 +204,8 @@
<Compile Include="Composing\WeightedCollectionBuilderBase.cs" />
<Compile Include="Configuration\CaseInsensitiveEnumConfigConverter.cs" />
<Compile Include="Configuration\CommaDelimitedConfigurationElement.cs" />
<Compile Include="ConfigsExtensions.cs" />
<Compile Include="Configuration\Configs.cs" />
<Compile Include="Configuration\CoreDebug.cs" />
<Compile Include="Configuration\Dashboard\AccessElement.cs" />
<Compile Include="Configuration\Dashboard\AccessRule.cs" />
@@ -257,7 +259,6 @@
<Compile Include="Configuration\OptionalCommaDelimitedConfigurationElement.cs" />
<Compile Include="Configuration\OptionalInnerTextConfigurationElement.cs" />
<Compile Include="Configuration\RawXmlConfigurationElement.cs" />
<Compile Include="Configuration\UmbracoConfig.cs" />
<Compile Include="Configuration\UmbracoConfigurationSection.cs" />
<Compile Include="Configuration\UmbracoSettings\AppCodeFileExtensionsCollection.cs" />
<Compile Include="Configuration\UmbracoSettings\AppCodeFileExtensionsElement.cs" />

View File

@@ -4,6 +4,8 @@ using Moq;
using NUnit.Framework;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing;
using Umbraco.Tests.Testing.Objects.Accessors;
@@ -48,16 +50,14 @@ namespace Umbraco.Tests.Cache.PublishedCache
</root>";
}
public override void SetUp()
protected override void Initialize()
{
base.SetUp();
base.Initialize();
_httpContextFactory = new FakeHttpContextFactory("~/Home");
var umbracoSettings = SettingsForTests.GenerateMockUmbracoSettings();
var globalSettings = SettingsForTests.GenerateMockGlobalSettings();
SettingsForTests.ConfigureSettings(umbracoSettings);
SettingsForTests.ConfigureSettings(globalSettings);
var umbracoSettings = Factory.GetInstance<IUmbracoSettingsSection>();
var globalSettings = Factory.GetInstance<IGlobalSettings>();
_xml = new XmlDocument();
_xml.LoadXml(GetXml());

View File

@@ -18,7 +18,8 @@ namespace Umbraco.Tests.Components
public class ComponentTests
{
private static readonly List<Type> Composed = new List<Type>();
private static readonly List<string> Initialized = new List<string>();
private static readonly List<Type> Initialized = new List<Type>();
private static readonly List<Type> Terminated = new List<Type>();
private static IFactory MockFactory(Action<Mock<IFactory>> setup = null)
{
@@ -64,13 +65,36 @@ namespace Umbraco.Tests.Components
var composition = new Composition(register, MockTypeLoader(), Mock.Of<IProfilingLogger>(), MockRuntimeState(RuntimeLevel.Unknown));
var types = TypeArray<Composer1, Composer2, Composer3, Composer4>();
var components = new Core.Components.Composers(composition, types, Mock.Of<IProfilingLogger>());
var composers = new Composers(composition, types, Mock.Of<IProfilingLogger>());
Composed.Clear();
// 2 is Core and requires 4
// 3 is User - goes away with RuntimeLevel.Unknown
// => reorder components accordingly
components.Compose();
composers.Compose();
AssertTypeArray(TypeArray<Composer1, Composer4, Composer2>(), Composed);
var factory = MockFactory(m =>
{
m.Setup(x => x.TryGetInstance(It.Is<Type>(t => t == typeof(ISomeResource)))).Returns(() => new SomeResource());
m.Setup(x => x.GetInstance(It.IsAny<Type>())).Returns<Type>((type) =>
{
if (type == typeof(Composer1)) return new Composer1();
if (type == typeof(Composer5)) return new Composer5();
if (type == typeof(Component5)) return new Component5(new SomeResource());
if (type == typeof(IProfilingLogger)) return new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>());
throw new NotSupportedException(type.FullName);
});
});
var builder = composition.WithCollectionBuilder<ComponentCollectionBuilder>();
builder.RegisterWith(register);
var components = builder.CreateCollection(factory);
Assert.IsEmpty(components);
components.Initialize();
Assert.IsEmpty(Initialized);
components.Terminate();
Assert.IsEmpty(Terminated);
}
[Test]
@@ -164,6 +188,10 @@ namespace Umbraco.Tests.Components
[Test]
public void Initialize()
{
Composed.Clear();
Initialized.Clear();
Terminated.Clear();
var register = MockRegister();
var factory = MockFactory(m =>
{
@@ -181,17 +209,22 @@ namespace Umbraco.Tests.Components
var types = new[] { typeof(Composer1), typeof(Composer5) };
var composers = new Composers(composition, types, Mock.Of<IProfilingLogger>());
Composed.Clear();
Initialized.Clear();
Assert.IsEmpty(Composed);
composers.Compose();
AssertTypeArray(TypeArray<Composer1, Composer5>(), Composed);
var builder = composition.WithCollectionBuilder<ComponentCollectionBuilder>();
builder.RegisterWith(register);
var components = builder.CreateCollection(factory);
Assert.AreEqual(2, Composed.Count);
Assert.AreEqual(typeof(Composer1), Composed[0]);
Assert.AreEqual(typeof(Composer5), Composed[1]);
Assert.AreEqual(1, Initialized.Count);
Assert.AreEqual("Umbraco.Tests.Components.ComponentTests+SomeResource", Initialized[0]);
Assert.IsEmpty(Initialized);
components.Initialize();
AssertTypeArray(TypeArray<Component5>(), Initialized);
Assert.IsEmpty(Terminated);
components.Terminate();
AssertTypeArray(TypeArray<Component5>(), Terminated);
}
[Test]
@@ -301,9 +334,6 @@ namespace Umbraco.Tests.Components
}
}
public class TestComponentBase : IComponent
{ }
public class Composer1 : TestComposerBase
{ }
@@ -326,11 +356,26 @@ namespace Umbraco.Tests.Components
}
}
public class Component5 : IComponent
public class TestComponentBase : IComponent
{
public virtual void Initialize()
{
Initialized.Add(GetType());
}
public virtual void Terminate()
{
Terminated.Add(GetType());
}
}
public class Component5 : TestComponentBase
{
private readonly ISomeResource _resource;
public Component5(ISomeResource resource)
{
Initialized.Add(resource.GetType().FullName);
_resource = resource;
}
}

View File

@@ -2,6 +2,7 @@
using System.Web.Routing;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
@@ -46,14 +47,13 @@ namespace Umbraco.Tests.Configurations
[TestCase("~/some-wacky/nestedPath", "/MyVirtualDir/NestedVDir/", "some-wacky-nestedpath")]
public void Umbraco_Mvc_Area(string path, string rootPath, string outcome)
{
var globalSettingsMock = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettingsMock = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettingsMock.Setup(x => x.Path).Returns(IOHelper.ResolveUrl(path));
SettingsForTests.ConfigureSettings(globalSettingsMock.Object);
SystemDirectories.Root = rootPath;
Assert.AreEqual(outcome, Current.Config.Global().GetUmbracoMvcArea());
Assert.AreEqual(outcome, Current.Configs.Global().GetUmbracoMvcArea());
}
[TestCase("/umbraco/editContent.aspx")]
[TestCase("/install/default.aspx")]
[TestCase("/install/")]
@@ -93,10 +93,9 @@ namespace Umbraco.Tests.Configurations
public void Is_Reserved_By_Route(string url, bool shouldMatch)
{
//reset the app config, we only want to test routes not the hard coded paths
var globalSettingsMock = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettingsMock = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettingsMock.Setup(x => x.ReservedPaths).Returns("");
globalSettingsMock.Setup(x => x.ReservedUrls).Returns("");
SettingsForTests.ConfigureSettings(globalSettingsMock.Object);
var routes = new RouteCollection();

View File

@@ -1,8 +1,9 @@
using System;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Strings;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing;
namespace Umbraco.Tests.CoreThings
@@ -10,14 +11,11 @@ namespace Umbraco.Tests.CoreThings
[TestFixture]
public class TryConvertToTests : UmbracoTestBase
{
public override void SetUp()
protected void Compose()
{
base.SetUp();
base.Compose();
var settings = SettingsForTests.GetDefaultUmbracoSettings();
// fixme - base should do it!
Composition.RegisterUnique<IShortStringHelper>(_ => new DefaultShortStringHelper(settings));
Composition.RegisterUnique<IShortStringHelper>(f => new DefaultShortStringHelper(f.GetInstance<IUmbracoSettingsSection>()));
}
[Test]

View File

@@ -26,10 +26,6 @@ namespace Umbraco.Tests.IO
[SetUp]
public void Setup()
{
//init the config singleton
var config = SettingsForTests.GetDefaultUmbracoSettings();
SettingsForTests.ConfigureSettings(config);
_register = RegisterFactory.Create();
var composition = new Composition(_register, new TypeLoader(), Mock.Of<IProfilingLogger>(), ComponentTests.MockRuntimeState(RuntimeLevel.Run));
@@ -39,10 +35,18 @@ namespace Umbraco.Tests.IO
composition.Register(_ => Mock.Of<IContentSection>());
composition.RegisterUnique<IMediaPathScheme, OriginalMediaPathScheme>();
composition.Configs.Add(SettingsForTests.GetDefaultGlobalSettings);
composition.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings);
composition.ComposeFileSystems();
composition.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings);
_factory = composition.CreateFactory();
Current.Reset();
Current.Factory = _factory;
// make sure we start clean
// because some tests will create corrupt or weird filesystems
FileSystems.Reset();
@@ -82,6 +86,16 @@ namespace Umbraco.Tests.IO
Assert.AreSame(fileSystem1, fileSystem2);
}
[Test]
public void Can_Unwrap_MediaFileSystem()
{
var fileSystem = _factory.GetInstance<IMediaFileSystem>();
var unwrapped = fileSystem.Unwrap();
Assert.IsNotNull(unwrapped);
var physical = unwrapped as PhysicalFileSystem;
Assert.IsNotNull(physical);
}
[Test]
public void Can_Delete_MediaFiles()
{

View File

@@ -6,6 +6,7 @@ using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web.Macros;
@@ -27,7 +28,9 @@ namespace Umbraco.Tests.Macros
new IsolatedRuntimeCache(type => new ObjectCacheRuntimeCacheProvider()));
//Current.ApplicationContext = new ApplicationContext(cacheHelper, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
Current.Config.SetUmbracoConfig(SettingsForTests.GetDefaultUmbracoSettings());
Current.Reset();
Current.UnlockConfigs();
Current.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings);
}
[TestCase("123", "IntProp", typeof(int))]

View File

@@ -90,7 +90,6 @@ namespace Umbraco.Tests.Misc
var settings = SettingsForTests.GenerateMockUmbracoSettings();
var requestMock = Mock.Get(settings.RequestHandler);
requestMock.Setup(x => x.AddTrailingSlash).Returns(trailingSlash);
SettingsForTests.ConfigureSettings(settings);
UriUtility.SetAppDomainAppVirtualPath("/");

View File

@@ -7,18 +7,14 @@ using System.Threading;
using Moq;
using Umbraco.Core;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Composing.Composers;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Serialization;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using Umbraco.Tests.TestHelpers.Stubs;
using Umbraco.Tests.Testing;
@@ -29,14 +25,6 @@ namespace Umbraco.Tests.Models
[TestFixture]
public class ContentTests : UmbracoTestBase
{
public override void SetUp()
{
base.SetUp();
var config = SettingsForTests.GetDefaultUmbracoSettings();
SettingsForTests.ConfigureSettings(config);
}
protected override void Compose()
{
base.Compose();

View File

@@ -1,6 +1,7 @@
using System;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core.Composing;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Tests.TestHelpers;
@@ -13,8 +14,9 @@ namespace Umbraco.Tests.Models
[SetUp]
public void Init()
{
var config = SettingsForTests.GetDefaultUmbracoSettings();
SettingsForTests.ConfigureSettings(config);
Current.Reset();
Current.UnlockConfigs();
Current.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings);
}
[Test]

View File

@@ -2,9 +2,10 @@
using System.Diagnostics;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core.Composing;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Serialization;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
namespace Umbraco.Tests.Models
@@ -12,6 +13,15 @@ namespace Umbraco.Tests.Models
[TestFixture]
public class MemberTests
{
[SetUp]
public void Setup()
{
Current.Reset();
Current.UnlockConfigs();
Current.Configs.Add(SettingsForTests.GetDefaultGlobalSettings);
Current.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings);
}
[Test]
public void Can_Deep_Clone()
{

View File

@@ -2,14 +2,24 @@
using System.Diagnostics;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core.Composing;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Serialization;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Models
{
[TestFixture]
public class UserTests
{
[SetUp]
public void Setup()
{
Current.Reset();
Current.UnlockConfigs();
Current.Configs.Add(SettingsForTests.GetDefaultGlobalSettings);
}
[Test]
public void Can_Deep_Clone()
{

View File

@@ -3,6 +3,7 @@ using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
@@ -26,6 +27,11 @@ namespace Umbraco.Tests.Models
// need to be able to retrieve them all...
Current.Reset();
var configs = new Configs();
configs.Add(SettingsForTests.GetDefaultGlobalSettings);
configs.Add(SettingsForTests.GetDefaultUmbracoSettings);
var factory = Mock.Of<IFactory>();
Current.Factory = factory;
@@ -53,12 +59,12 @@ namespace Umbraco.Tests.Models
.Setup(x => x.GetInstance(It.IsAny<Type>()))
.Returns<Type>(x =>
{
if (x == typeof(Configs)) return configs;
if (x == typeof(PropertyEditorCollection)) return propertyEditors;
if (x == typeof(ServiceContext)) return serviceContext;
if (x == typeof(ILocalizedTextService)) return serviceContext.LocalizationService;
throw new Exception("oops");
throw new NotSupportedException(x.FullName);
});
}
[Test]
@@ -429,7 +435,7 @@ namespace Umbraco.Tests.Models
Assert.IsTrue(content.IsCultureAvailable(langUk));
Assert.IsFalse(content.IsCulturePublished(langUk));
Assert.IsNull(content.GetPublishName(langUk));
Assert.IsNull(content.GetPublishDate(langUk)); // not published
Assert.IsNull(content.GetPublishDate(langUk)); // not published
Assert.IsFalse(content.IsCultureAvailable(langEs));
Assert.IsFalse(content.IsCultureEdited(langEs)); // not avail, so... not edited
@@ -437,7 +443,7 @@ namespace Umbraco.Tests.Models
// not published!
Assert.IsNull(content.GetPublishName(langEs));
Assert.IsNull(content.GetPublishDate(langEs));
Assert.IsNull(content.GetPublishDate(langEs));
// cannot test IsCultureEdited here - as that requires the content service and repository
// see: ContentServiceTests.Can_SaveRead_Variations

View File

@@ -35,8 +35,11 @@ namespace Umbraco.Tests.PublishedContent
// this test implements a full standalone NuCache (based upon a test IDataSource, does not
// use any local db files, does not rely on any database) - and tests variations
SettingsForTests.ConfigureSettings(SettingsForTests.GenerateMockUmbracoSettings());
var globalSettings = Current.Config.Global();
Current.Reset();
Current.UnlockConfigs();
Current.Configs.Add(SettingsForTests.GenerateMockUmbracoSettings);
Current.Configs.Add<IGlobalSettings>(() => new GlobalSettings());
var globalSettings = Current.Configs.Global();
// create a content node kit
var kit = new ContentNodeKit

View File

@@ -104,7 +104,7 @@ namespace Umbraco.Tests.PublishedContent
Assert.AreEqual("<div>This is some content</div>", propVal2.ToString());
var propVal3 = publishedMedia.Value("Content");
Assert.IsInstanceOf<IHtmlString>(propVal3);
Assert.IsInstanceOf<IHtmlString>(propVal3);
Assert.AreEqual("<div>This is some content</div>", propVal3.ToString());
}
@@ -461,10 +461,6 @@ namespace Umbraco.Tests.PublishedContent
[Test]
public void Convert_From_Standard_Xml()
{
var config = SettingsForTests.GenerateMockUmbracoSettings();
SettingsForTests.ConfigureSettings(config);
var nodeId = 2112;
var xml = XElement.Parse(@"<Image id=""2112"" version=""5b3e46ab-3e37-4cfa-ab70-014234b5bd39"" parentID=""2222"" level=""3"" writerID=""0"" nodeType=""1032"" template=""0"" sortOrder=""1"" createDate=""2010-05-19T17:32:46"" updateDate=""2010-05-19T17:32:46"" nodeName=""Sam's Umbraco Image"" urlName=""acnestressscrub"" writerName=""Administrator"" nodeTypeAlias=""Image"" path=""-1,1111,2222,2112"" isDoc="""">

View File

@@ -1,5 +1,7 @@
using Moq;
using NUnit.Framework;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web.Routing;
using Umbraco.Core.Models;
@@ -27,10 +29,8 @@ namespace Umbraco.Tests.Routing
[TestCase("/home/Sub1.aspx/blah")]
public void Match_Document_By_Url_With_Template(string urlAsString)
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var template1 = CreateTemplate("test");
var template2 = CreateTemplate("blah");

View File

@@ -2,6 +2,7 @@
using System.Globalization;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
@@ -28,16 +29,15 @@ namespace Umbraco.Tests.Routing
[TestCase("/test-page", 1172)]
public void Match_Document_By_Url_Hide_Top_Level(string urlString, int expectedId)
{
var globalSettingsMock = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettingsMock = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettingsMock.Setup(x => x.HideTopLevelNodeFromPath).Returns(true);
SettingsForTests.ConfigureSettings(globalSettingsMock.Object);
var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettingsMock.Object);
var publishedRouter = CreatePublishedRouter();
var frequest = publishedRouter.CreateRequest(umbracoContext);
var lookup = new ContentFinderByUrl(Logger);
Assert.IsTrue(Current.Config.Global().HideTopLevelNodeFromPath);
Assert.IsTrue(Current.Configs.Global().HideTopLevelNodeFromPath);
// fixme debugging - going further down, the routes cache is NOT empty?!
if (urlString == "/home/sub1")
@@ -64,16 +64,15 @@ namespace Umbraco.Tests.Routing
[TestCase("/home/Sub1.aspx", 1173)]
public void Match_Document_By_Url(string urlString, int expectedId)
{
var globalSettingsMock = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettingsMock = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettingsMock.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettingsMock.Object);
var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettingsMock.Object);
var publishedRouter = CreatePublishedRouter();
var frequest = publishedRouter.CreateRequest(umbracoContext);
var lookup = new ContentFinderByUrl(Logger);
Assert.IsFalse(Current.Config.Global().HideTopLevelNodeFromPath);
Assert.IsFalse(Current.Configs.Global().HideTopLevelNodeFromPath);
var result = lookup.TryFindContent(frequest);
@@ -90,9 +89,8 @@ namespace Umbraco.Tests.Routing
[TestCase("/home/sub1/custom-sub-4-with-æøå", 1180)]
public void Match_Document_By_Url_With_Special_Characters(string urlString, int expectedId)
{
var globalSettingsMock = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettingsMock = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettingsMock.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettingsMock.Object);
var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettingsMock.Object);
var publishedRouter = CreatePublishedRouter();
@@ -118,9 +116,8 @@ namespace Umbraco.Tests.Routing
[TestCase("/home/sub1/custom-sub-4-with-æøå", 1180)]
public void Match_Document_By_Url_With_Special_Characters_Using_Hostname(string urlString, int expectedId)
{
var globalSettingsMock = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettingsMock = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettingsMock.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettingsMock.Object);
var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettingsMock.Object);
var publishedRouter = CreatePublishedRouter();
@@ -148,9 +145,8 @@ namespace Umbraco.Tests.Routing
[TestCase("/æøå/home/sub1/custom-sub-4-with-æøå", 1180)]
public void Match_Document_By_Url_With_Special_Characters_In_Hostname(string urlString, int expectedId)
{
var globalSettingsMock = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettingsMock = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettingsMock.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettingsMock.Object);
var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettingsMock.Object);
var publishedRouter = CreatePublishedRouter();

View File

@@ -1,5 +1,7 @@
using Moq;
using NUnit.Framework;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web.Routing;
@@ -124,10 +126,9 @@ namespace Umbraco.Tests.Routing
{
SetDomains3();
var globalSettingsMock = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettingsMock = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettingsMock.Setup(x => x.HideTopLevelNodeFromPath).Returns(true);
SettingsForTests.ConfigureSettings(globalSettingsMock.Object);
var umbracoContext = GetUmbracoContext(url, globalSettings:globalSettingsMock.Object);
var publishedRouter = CreatePublishedRouter(Factory);
var frequest = publishedRouter.CreateRequest(umbracoContext);
@@ -167,9 +168,8 @@ namespace Umbraco.Tests.Routing
// defaults depend on test environment
expectedCulture = expectedCulture ?? System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
var globalSettingsMock = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettingsMock = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettingsMock.Setup(x => x.HideTopLevelNodeFromPath).Returns(true);
SettingsForTests.ConfigureSettings(globalSettingsMock.Object);
var umbracoContext = GetUmbracoContext(url, globalSettings:globalSettingsMock.Object);
var publishedRouter = CreatePublishedRouter(Factory);

View File

@@ -5,6 +5,7 @@ using Umbraco.Tests.TestHelpers;
using Umbraco.Web.Routing;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
namespace Umbraco.Tests.Routing
{
@@ -265,9 +266,8 @@ namespace Umbraco.Tests.Routing
{
SetDomains1();
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext(inputUrl, globalSettings:globalSettings.Object);
var publishedRouter = CreatePublishedRouter(Factory);
@@ -315,9 +315,8 @@ namespace Umbraco.Tests.Routing
// defaults depend on test environment
expectedCulture = expectedCulture ?? System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext(inputUrl, globalSettings:globalSettings.Object);
var publishedRouter = CreatePublishedRouter(Factory);
@@ -371,9 +370,8 @@ namespace Umbraco.Tests.Routing
{
SetDomains3();
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext(inputUrl, globalSettings:globalSettings.Object);
var publishedRouter = CreatePublishedRouter(Factory);
var frequest = publishedRouter.CreateRequest(umbracoContext);

View File

@@ -3,10 +3,11 @@ using System.Globalization;
using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using Umbraco.Web.Routing;
@@ -15,17 +16,6 @@ namespace Umbraco.Tests.Routing
[TestFixture]
public class GetContentUrlsTests : UrlRoutingTestBase
{
private IUmbracoSettingsSection _umbracoSettings;
public override void SetUp()
{
base.SetUp();
//generate new mock settings and assign so we can configure in individual tests
_umbracoSettings = SettingsForTests.GenerateMockUmbracoSettings();
SettingsForTests.ConfigureSettings(_umbracoSettings);
}
private ILocalizedTextService GetTextService()
{
var textService = Mock.Of<ILocalizedTextService>(
@@ -80,8 +70,10 @@ namespace Umbraco.Tests.Routing
content.Path = "-1,1046";
content.Published = true;
var umbracoSettings = Current.Configs.Settings();
var umbContext = GetUmbracoContext("http://localhost:8000",
urlProviders: new []{ new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper()) });
urlProviders: new []{ new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper()) });
var publishedRouter = CreatePublishedRouter(Factory,
contentFinders:new ContentFinderCollection(new[]{new ContentFinderByUrl(Logger) }));
var urls = content.GetContentUrls(publishedRouter,
@@ -110,8 +102,10 @@ namespace Umbraco.Tests.Routing
child.Path = "-1,1046,1173";
child.Published = true;
var umbracoSettings = Current.Configs.Settings();
var umbContext = GetUmbracoContext("http://localhost:8000",
urlProviders: new[] { new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper()) });
urlProviders: new[] { new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper()) });
var publishedRouter = CreatePublishedRouter(Factory,
contentFinders: new ContentFinderCollection(new[] { new ContentFinderByUrl(Logger) }));
var urls = child.GetContentUrls(publishedRouter,

View File

@@ -6,7 +6,7 @@ using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Tests.TestHelpers;
@@ -28,15 +28,10 @@ namespace Umbraco.Tests.Routing
Composition.Register<ISiteDomainHelper, SiteDomainHelper>();
}
private IUmbracoSettingsSection _umbracoSettings;
public override void SetUp()
protected override void ComposeSettings()
{
base.SetUp();
//generate new mock settings and assign so we can configure in individual tests
_umbracoSettings = SettingsForTests.GenerateMockUmbracoSettings();
SettingsForTests.ConfigureSettings(_umbracoSettings);
Composition.Configs.Add(SettingsForTests.GenerateMockUmbracoSettings);
Composition.Configs.Add(SettingsForTests.GenerateMockGlobalSettings);
}
/// <summary>
@@ -46,17 +41,18 @@ namespace Umbraco.Tests.Routing
[Test]
public void Ensure_Cache_Is_Correct()
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoSettings = Current.Configs.Settings();
var umbracoContext = GetUmbracoContext("/test", 1111, urlProviders: new[]
{
new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
}, globalSettings: globalSettings.Object);
var requestHandlerMock = Mock.Get(_umbracoSettings.RequestHandler);
var requestHandlerMock = Mock.Get(umbracoSettings.RequestHandler);
requestHandlerMock.Setup(x => x.AddTrailingSlash).Returns(false);// (cached routes have none)
var samples = new Dictionary<int, string> {
@@ -109,17 +105,18 @@ namespace Umbraco.Tests.Routing
[TestCase(1172, "/test-page/")]
public void Get_Url_Not_Hiding_Top_Level(int nodeId, string niceUrlMatch)
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoSettings = Current.Configs.Settings();
var umbracoContext = GetUmbracoContext("/test", 1111, urlProviders: new[]
{
new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
}, globalSettings: globalSettings.Object);
var requestMock = Mock.Get(_umbracoSettings.RequestHandler);
var requestMock = Mock.Get(umbracoSettings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
var result = umbracoContext.UrlProvider.GetUrl(nodeId);
@@ -139,17 +136,18 @@ namespace Umbraco.Tests.Routing
[TestCase(1172, "/test-page/")] // not hidden because not first root
public void Get_Url_Hiding_Top_Level(int nodeId, string niceUrlMatch)
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(true);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoSettings = Current.Configs.Settings();
var umbracoContext = GetUmbracoContext("/test", 1111, urlProviders: new[]
{
new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
}, globalSettings: globalSettings.Object);
var requestMock = Mock.Get(_umbracoSettings.RequestHandler);
var requestMock = Mock.Get(umbracoSettings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
var result = umbracoContext.UrlProvider.GetUrl(nodeId);
@@ -161,12 +159,13 @@ namespace Umbraco.Tests.Routing
{
const string currentUri = "http://example.us/test";
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var requestMock = Mock.Get(_umbracoSettings.RequestHandler);
var umbracoSettings = Current.Configs.Settings();
var requestMock = Mock.Get(umbracoSettings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty<string>(), Enumerable.Empty<PublishedPropertyType>(), ContentVariation.Culture);
@@ -188,9 +187,9 @@ namespace Umbraco.Tests.Routing
snapshotService.Setup(x => x.CreatePublishedSnapshot(It.IsAny<string>()))
.Returns(snapshot);
var umbracoContext = GetUmbracoContext(currentUri, umbracoSettings: _umbracoSettings,
var umbracoContext = GetUmbracoContext(currentUri, umbracoSettings: umbracoSettings,
urlProviders: new[] {
new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
},
globalSettings: globalSettings.Object,
snapshotService: snapshotService.Object);
@@ -209,12 +208,13 @@ namespace Umbraco.Tests.Routing
{
const string currentUri = "http://example.fr/test";
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var requestMock = Mock.Get(_umbracoSettings.RequestHandler);
var umbracoSettings = Current.Configs.Settings();
var requestMock = Mock.Get(umbracoSettings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty<string>(), Enumerable.Empty<PublishedPropertyType>(), ContentVariation.Culture);
@@ -245,9 +245,9 @@ namespace Umbraco.Tests.Routing
snapshotService.Setup(x => x.CreatePublishedSnapshot(It.IsAny<string>()))
.Returns(snapshot);
var umbracoContext = GetUmbracoContext(currentUri, umbracoSettings: _umbracoSettings,
var umbracoContext = GetUmbracoContext(currentUri, umbracoSettings: umbracoSettings,
urlProviders: new[] {
new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
},
globalSettings: globalSettings.Object,
snapshotService: snapshotService.Object);
@@ -266,12 +266,13 @@ namespace Umbraco.Tests.Routing
{
const string currentUri = "http://example.us/test";
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var requestMock = Mock.Get(_umbracoSettings.RequestHandler);
var umbracoSettings = Current.Configs.Settings();
var requestMock = Mock.Get(umbracoSettings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty<string>(), Enumerable.Empty<PublishedPropertyType>(), ContentVariation.Culture);
@@ -302,9 +303,9 @@ namespace Umbraco.Tests.Routing
snapshotService.Setup(x => x.CreatePublishedSnapshot(It.IsAny<string>()))
.Returns(snapshot);
var umbracoContext = GetUmbracoContext(currentUri, umbracoSettings: _umbracoSettings,
var umbracoContext = GetUmbracoContext(currentUri, umbracoSettings: umbracoSettings,
urlProviders: new[] {
new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
},
globalSettings: globalSettings.Object,
snapshotService: snapshotService.Object);
@@ -319,17 +320,18 @@ namespace Umbraco.Tests.Routing
[Test]
public void Get_Url_Relative_Or_Absolute()
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var requestMock = Mock.Get(_umbracoSettings.RequestHandler);
var umbracoSettings = Current.Configs.Settings();
var requestMock = Mock.Get(umbracoSettings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
var umbracoContext = GetUmbracoContext("http://example.com/test", 1111, umbracoSettings: _umbracoSettings, urlProviders: new[]
var umbracoContext = GetUmbracoContext("http://example.com/test", 1111, umbracoSettings: umbracoSettings, urlProviders: new[]
{
new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
}, globalSettings: globalSettings.Object);
Assert.AreEqual("/home/sub1/custom-sub-1/", umbracoContext.UrlProvider.GetUrl(1177));
@@ -345,18 +347,19 @@ namespace Umbraco.Tests.Routing
[Test]
public void Get_Url_Unpublished()
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoSettings = Current.Configs.Settings();
var umbracoContext = GetUmbracoContext("http://example.com/test", 1111, urlProviders: new[]
{
new DefaultUrlProvider(_umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, new SiteDomainHelper())
}, globalSettings: globalSettings.Object);
//mock the Umbraco settings that we need
var requestMock = Mock.Get(_umbracoSettings.RequestHandler);
var requestMock = Mock.Get(umbracoSettings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
Assert.AreEqual("#", umbracoContext.UrlProvider.GetUrl(999999));

View File

@@ -1,6 +1,8 @@
using System;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing;
@@ -193,9 +195,8 @@ DetermineRouteById(id):
[TestCase(2006, false, "/x/b/e")]
public void GetRouteByIdNoHide(int id, bool hide, string expected)
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(hide);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("/test", 0, globalSettings: globalSettings.Object);
var cache = umbracoContext.ContentCache as PublishedContentCache;
@@ -218,9 +219,8 @@ DetermineRouteById(id):
[TestCase(2006, true, "/b/e")] // risky!
public void GetRouteByIdHide(int id, bool hide, string expected)
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(hide);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("/test", 0, globalSettings: globalSettings.Object);
var cache = umbracoContext.ContentCache as PublishedContentCache;
@@ -233,14 +233,13 @@ DetermineRouteById(id):
[Test]
public void GetRouteByIdCache()
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("/test", 0, globalSettings:globalSettings.Object);
var cache = umbracoContext.ContentCache as PublishedContentCache;
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
var route = cache.GetRouteById(false, 1000);
Assert.AreEqual("/a", route);
@@ -265,9 +264,8 @@ DetermineRouteById(id):
[TestCase("/x", false, 2000)]
public void GetByRouteNoHide(string route, bool hide, int expected)
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(hide);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("/test", 0, globalSettings:globalSettings.Object);
var cache = umbracoContext.ContentCache as PublishedContentCache;
@@ -297,9 +295,8 @@ DetermineRouteById(id):
[TestCase("/b/c", true, 1002)] // (hence the 2005 collision)
public void GetByRouteHide(string route, bool hide, int expected)
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(hide);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("/test", 0, globalSettings:globalSettings.Object);
var cache = umbracoContext.ContentCache as PublishedContentCache;
@@ -321,14 +318,13 @@ DetermineRouteById(id):
[Test]
public void GetByRouteCache()
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("/test", 0, globalSettings:globalSettings.Object);
var cache = umbracoContext.ContentCache as PublishedContentCache;
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
var content = cache.GetByRoute(false, "/a/b/c");
Assert.IsNotNull(content);
Assert.AreEqual(1002, content.Id);

View File

@@ -5,6 +5,7 @@ using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
@@ -178,10 +179,9 @@ namespace Umbraco.Tests.Routing
var request = Mock.Get(settings.RequestHandler);
request.Setup(x => x.UseDomainPrefixes).Returns(false);
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false); // ignored w/domains
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings, urlProviders: new[]
{
@@ -214,10 +214,9 @@ namespace Umbraco.Tests.Routing
var request = Mock.Get(settings.RequestHandler);
request.Setup(x => x.UseDomainPrefixes).Returns(false);
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false); // ignored w/domains
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings, urlProviders: new[]
{
@@ -242,10 +241,9 @@ namespace Umbraco.Tests.Routing
var request = Mock.Get(settings.RequestHandler);
request.Setup(x => x.UseDomainPrefixes).Returns(false);
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false); // ignored w/domains
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings, urlProviders: new[]
{
@@ -276,10 +274,9 @@ namespace Umbraco.Tests.Routing
var request = Mock.Get(settings.RequestHandler);
request.Setup(x => x.UseDomainPrefixes).Returns(false);
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false); // ignored w/domains
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings, urlProviders: new[]
{
@@ -300,10 +297,9 @@ namespace Umbraco.Tests.Routing
var request = Mock.Get(settings.RequestHandler);
request.Setup(x => x.UseDomainPrefixes).Returns(false);
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false); // ignored w/domains
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("/test", 1111, umbracoSettings: settings, urlProviders: new[]
{
@@ -367,10 +363,9 @@ namespace Umbraco.Tests.Routing
var requestMock = Mock.Get(settings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false); // ignored w/domains
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("http://domain1.com/test", 1111, umbracoSettings: settings, urlProviders: new[]
{
@@ -399,10 +394,9 @@ namespace Umbraco.Tests.Routing
{
var settings = SettingsForTests.GenerateMockUmbracoSettings();
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false); // ignored w/domains
SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext("http://domain1.com/en/test", 1111, umbracoSettings: settings, urlProviders: new[]
{

View File

@@ -3,6 +3,7 @@ using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web.PublishedCache.XmlPublishedCache;
@@ -29,10 +30,9 @@ namespace Umbraco.Tests.Routing
[Test]
public void DoNotPolluteCache()
{
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettings = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true);
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
var settings = SettingsForTests.GenerateMockUmbracoSettings();
var request = Mock.Get(settings.RequestHandler);

View File

@@ -8,6 +8,7 @@ using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Components;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Logging;
@@ -27,12 +28,7 @@ namespace Umbraco.Tests.Runtimes
public void SetUp()
{
TestComponent.Reset();
// cannot boot runtime without some configuration
var umbracoSettings = SettingsForTests.GenerateMockUmbracoSettings();
var globalSettings = SettingsForTests.GenerateMockGlobalSettings();
SettingsForTests.ConfigureSettings(umbracoSettings);
SettingsForTests.ConfigureSettings(globalSettings);
Current.Reset();
}
public void TearDown()
@@ -106,6 +102,14 @@ namespace Umbraco.Tests.Runtimes
return mock.Object;
}
protected override Configs GetConfigs()
{
var configs = new Configs();
configs.Add(SettingsForTests.GetDefaultGlobalSettings);
configs.Add(SettingsForTests.GetDefaultUmbracoSettings);
return configs;
}
// fixme so how the f* should we do it now?
/*
// pretend we have the proper migration
@@ -191,8 +195,7 @@ namespace Umbraco.Tests.Runtimes
{
// test flags
public static bool Ctored;
public static bool Initialized1;
public static bool Initialized2;
public static bool Initialized;
public static bool Terminated;
public static IProfilingLogger ProfilingLogger;
@@ -200,7 +203,7 @@ namespace Umbraco.Tests.Runtimes
public static void Reset()
{
Ctored = Initialized1 = Initialized2 = Terminated = false;
Ctored = Initialized = Terminated = false;
ProfilingLogger = null;
}
@@ -210,10 +213,19 @@ namespace Umbraco.Tests.Runtimes
ProfilingLogger = proflog;
}
public void Initialize()
{
Initialized = true;
}
public void Terminate()
{
Terminated = true;
}
public void Dispose()
{
Disposed = true;
Terminated = true;
}
}
}

View File

@@ -107,6 +107,10 @@ namespace Umbraco.Tests.Runtimes
.Clear()
.Append<DistributedCacheBinderComponent>();
// configure
composition.Configs.Add(SettingsForTests.GetDefaultGlobalSettings);
composition.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings);
// create and register the factory
Current.Factory = factory = composition.CreateFactory();
@@ -150,11 +154,6 @@ namespace Umbraco.Tests.Runtimes
// done installing
runtimeState.Level = RuntimeLevel.Run;
var globalSettings = SettingsForTests.GetDefaultGlobalSettings();
SettingsForTests.ConfigureSettings(globalSettings);
var umbracoSettings = SettingsForTests.GetDefaultUmbracoSettings();
SettingsForTests.ConfigureSettings(umbracoSettings);
// instantiate to register events
// should be done by Initialize?
// should we invoke Initialize?
@@ -260,9 +259,9 @@ namespace Umbraco.Tests.Runtimes
// get the components
// all of them?
var composerTypes = typeLoader.GetTypes<IComposer>();
// filtered?
//var componentTypes = typeLoader.GetTypes<IUmbracoComponent>()
// .Where(x => !x.FullName.StartsWith("Umbraco.Web"));
// filtered
composerTypes = composerTypes
.Where(x => !x.FullName.StartsWith("Umbraco.Tests"));
// single?
//var componentTypes = new[] { typeof(CoreRuntimeComponent) };
var composers = new Composers(composition, composerTypes, profilingLogger);

View File

@@ -3,7 +3,6 @@ using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Components;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
@@ -13,7 +12,6 @@ using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Services;
using Umbraco.Tests.Components;
@@ -42,6 +40,9 @@ namespace Umbraco.Tests.Scoping
composition.RegisterUnique(factory => new FileSystems(factory, factory.TryGetInstance<ILogger>()));
composition.WithCollectionBuilder<MapperCollectionBuilder>();
composition.Configs.Add(SettingsForTests.GetDefaultGlobalSettings);
composition.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings);
Current.Reset();
Current.Factory = composition.CreateFactory();

View File

@@ -5,6 +5,7 @@ using Moq;
using NUnit.Framework;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
@@ -39,6 +40,12 @@ namespace Umbraco.Tests.Scoping
.Add(() => Composition.TypeLoader.GetCacheRefreshers());
}
protected override void ComposeSettings()
{
Composition.Configs.Add(SettingsForTests.GenerateMockUmbracoSettings);
Composition.Configs.Add(SettingsForTests.GenerateMockGlobalSettings);
}
[TearDown]
public void Teardown()
{
@@ -79,10 +86,8 @@ namespace Umbraco.Tests.Scoping
Assert.AreSame(XmlStore, ((PublishedContentCache) umbracoContext.ContentCache).XmlStore);
// settings
var settings = SettingsForTests.GenerateMockUmbracoSettings();
var contentMock = Mock.Get(settings.Content);
var contentMock = Mock.Get(Factory.GetInstance<IUmbracoSettingsSection>().Content);
contentMock.Setup(x => x.XmlCacheEnabled).Returns(false);
SettingsForTests.ConfigureSettings(settings);
// create document type, document
var contentType = new ContentType(-1) { Alias = "CustomDocument", Name = "Custom Document" };
@@ -200,9 +205,8 @@ namespace Umbraco.Tests.Scoping
// settings
var settings = SettingsForTests.GenerateMockUmbracoSettings();
var contentMock = Mock.Get(settings.Content);
var contentMock = Mock.Get(Factory.GetInstance<IUmbracoSettingsSection>().Content);
contentMock.Setup(x => x.XmlCacheEnabled).Returns(false);
SettingsForTests.ConfigureSettings(settings);
// create document type
var contentType = new ContentType(-1) { Alias = "CustomDocument", Name = "Custom Document" };

View File

@@ -792,6 +792,54 @@ namespace Umbraco.Tests.Services
}
[Test]
public void Pending_Invariant_Property_Changes_Affect_Default_Language_Edited_State()
{
// Arrange
var langGB = new Language("en-GB") { IsDefault = true };
var langFr = new Language("fr-FR");
ServiceContext.LocalizationService.Save(langFr);
ServiceContext.LocalizationService.Save(langGB);
var contentType = MockedContentTypes.CreateMetaContentType();
contentType.Variations = ContentVariation.Culture;
foreach(var prop in contentType.PropertyTypes)
prop.Variations = ContentVariation.Culture;
var keywordsProp = contentType.PropertyTypes.Single(x => x.Alias == "metakeywords");
keywordsProp.Variations = ContentVariation.Nothing; // this one is invariant
ServiceContext.ContentTypeService.Save(contentType);
IContent content = new Content("content", -1, contentType);
content.SetCultureName("content-en", langGB.IsoCode);
content.SetCultureName("content-fr", langFr.IsoCode);
content.PublishCulture(langGB.IsoCode);
content.PublishCulture(langFr.IsoCode);
Assert.IsTrue(ServiceContext.ContentService.SavePublishing(content).Success);
//re-get
content = ServiceContext.ContentService.GetById(content.Id);
Assert.AreEqual(PublishedState.Published, content.PublishedState);
Assert.IsTrue(content.IsCulturePublished(langGB.IsoCode));
Assert.IsTrue(content.IsCulturePublished(langFr.IsoCode));
Assert.IsFalse(content.IsCultureEdited(langGB.IsoCode));
Assert.IsFalse(content.IsCultureEdited(langFr.IsoCode));
//update the invariant property and save a pending version
content.SetValue("metakeywords", "hello");
ServiceContext.ContentService.Save(content);
//re-get
content = ServiceContext.ContentService.GetById(content.Id);
Assert.AreEqual(PublishedState.Published, content.PublishedState);
Assert.IsTrue(content.IsCulturePublished(langGB.IsoCode));
Assert.IsTrue(content.IsCulturePublished(langFr.IsoCode));
Assert.IsTrue(content.IsCultureEdited(langGB.IsoCode));
Assert.IsFalse(content.IsCultureEdited(langFr.IsoCode));
}
[Test]
public void Can_Publish_Content_Variation_And_Detect_Changed_Cultures()
{

View File

@@ -9,15 +9,6 @@ namespace Umbraco.Tests.Strings
[TestFixture]
public class CmsHelperCasingTests : UmbracoTestBase
{
[SetUp]
public void Setup()
{
//set default config
var config = SettingsForTests.GetDefaultUmbracoSettings();
SettingsForTests.ConfigureSettings(config);
}
[TestCase("thisIsTheEnd", "This Is The End")]
[TestCase("th", "Th")]
[TestCase("t", "t")]

View File

@@ -123,7 +123,6 @@ namespace Umbraco.Tests.Strings
var contentMock = Mock.Get(settings.RequestHandler);
contentMock.Setup(x => x.CharCollection).Returns(Enumerable.Empty<IChar>());
contentMock.Setup(x => x.ConvertUrlsToAscii).Returns(false);
SettingsForTests.ConfigureSettings(settings);
const string input1 = "ÆØÅ and æøå and 中文测试 and אודות האתר and größer БбДдЖж page";
const string input2 = "ÆØÅ and æøå and größer БбДдЖж page";

View File

@@ -1,9 +1,7 @@
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Configuration;
using Moq;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
@@ -12,22 +10,6 @@ namespace Umbraco.Tests.TestHelpers
{
public class SettingsForTests
{
public static void ConfigureSettings(IGlobalSettings settings)
{
Current.Config.SetGlobalConfig(settings);
}
// umbracoSettings
/// <summary>
/// Sets the umbraco settings singleton to the object specified
/// </summary>
/// <param name="settings"></param>
public static void ConfigureSettings(IUmbracoSettingsSection settings)
{
Current.Config.SetUmbracoConfig(settings);
}
public static IGlobalSettings GenerateMockGlobalSettings()
{
var config = Mock.Of<IGlobalSettings>(
@@ -132,8 +114,6 @@ namespace Umbraco.Tests.TestHelpers
private static void ResetSettings()
{
_defaultGlobalSettings = null;
ConfigureSettings(GetDefaultUmbracoSettings());
ConfigureSettings(GetDefaultGlobalSettings());
}
private static IUmbracoSettingsSection _defaultUmbracoSettings;

View File

@@ -131,9 +131,8 @@ namespace Umbraco.Tests.TestHelpers
}
// ensure the configuration matches the current version for tests
var globalSettingsMock = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
var globalSettingsMock = Mock.Get(Factory.GetInstance<IGlobalSettings>()); //this will modify the IGlobalSettings instance stored in the container
globalSettingsMock.Setup(x => x.ConfigurationStatus).Returns(UmbracoVersion.Current.ToString(3));
SettingsForTests.ConfigureSettings(globalSettingsMock.Object);
using (ProfilingLogger.TraceDuration<TestWithDatabaseBase>("Initialize database."))
{

View File

@@ -287,25 +287,25 @@ namespace Umbraco.Tests.Testing
// create the schema
}
protected virtual void ComposeSettings()
{
Composition.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings);
Composition.Configs.Add(SettingsForTests.GetDefaultGlobalSettings);
}
protected virtual void ComposeApplication(bool withApplication)
{
if (withApplication == false) return;
ComposeSettings();
var umbracoSettings = SettingsForTests.GetDefaultUmbracoSettings();
var globalSettings = SettingsForTests.GetDefaultGlobalSettings();
//apply these globally
SettingsForTests.ConfigureSettings(umbracoSettings);
SettingsForTests.ConfigureSettings(globalSettings);
if (withApplication == false) return;
// default Datalayer/Repositories/SQL/Database/etc...
Composition.ComposeRepositories();
// register basic stuff that might need to be there for some container resolvers to work
Composition.RegisterUnique(factory => umbracoSettings);
Composition.RegisterUnique(factory => globalSettings);
Composition.RegisterUnique(factory => umbracoSettings.Content);
Composition.RegisterUnique(factory => umbracoSettings.Templates);
Composition.RegisterUnique(factory => umbracoSettings.WebRouting);
Composition.RegisterUnique(factory => factory.GetInstance<IUmbracoSettingsSection>().Content);
Composition.RegisterUnique(factory => factory.GetInstance<IUmbracoSettingsSection>().Templates);
Composition.RegisterUnique(factory => factory.GetInstance<IUmbracoSettingsSection>().WebRouting);
Composition.RegisterUnique<IExamineManager>(factory => ExamineManager.Instance);

View File

@@ -37,17 +37,19 @@ namespace Umbraco.Tests.Web
var serviceContext = ServiceContext.CreatePartial(entityService: entityService.Object);
// fixme - bad in a unit test - but Udi has a static ctor that wants it?!
var container = new Mock<IFactory>();
container.Setup(x => x.GetInstance(typeof(TypeLoader))).Returns(
var factory = new Mock<IFactory>();
factory.Setup(x => x.GetInstance(typeof(TypeLoader))).Returns(
new TypeLoader(NullCacheProvider.Instance, LocalTempStorage.Default, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>())));
container.Setup(x => x.GetInstance(typeof (ServiceContext))).Returns(serviceContext);
Current.Factory = container.Object;
factory.Setup(x => x.GetInstance(typeof (ServiceContext))).Returns(serviceContext);
var settings = SettingsForTests.GetDefaultUmbracoSettings();
factory.Setup(x => x.GetInstance(typeof(IUmbracoSettingsSection))).Returns(settings);
Current.Factory = factory.Object;
Umbraco.Web.Composing.Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
Udi.ResetUdiTypes();
Current.Config.SetUmbracoConfig(SettingsForTests.GetDefaultUmbracoSettings());
}
[TearDown]

View File

@@ -5152,14 +5152,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -5174,20 +5172,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -5304,8 +5299,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"ini": {
"version": "1.3.5",
@@ -5317,7 +5311,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -5332,7 +5325,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -5340,14 +5332,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@@ -5366,7 +5356,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -5447,8 +5436,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -5460,7 +5448,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@@ -5582,7 +5569,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",

View File

@@ -18,6 +18,7 @@
<umb-toggle
checked="vm.checked"
disabled="vm.disabled"
on-click="vm.toggle()"
show-labels="true"
label-on="Start"
@@ -38,6 +39,7 @@
var vm = this;
vm.checked = false;
vm.disabled = false;
vm.toggle = toggle;
@@ -52,6 +54,7 @@
</pre>
@param {boolean} checked Set to <code>true</code> or <code>false</code> to toggle the switch.
@param {boolean} disabled Set to <code>true</code> or <code>false</code> to disable the switch.
@param {callback} onClick The function which should be called when the toggle is clicked.
@param {string=} showLabels Set to <code>true</code> or <code>false</code> to show a "On" or "Off" label next to the switch.
@param {string=} labelOn Set a custom label for when the switched is turned on. It will default to "On".
@@ -115,6 +118,7 @@
templateUrl: 'views/components/buttons/umb-toggle.html',
scope: {
checked: "=",
disabled: "=",
onClick: "&",
labelOn: "@?",
labelOff: "@?",

View File

@@ -109,7 +109,7 @@
});
}
}));
}
/**
@@ -308,6 +308,18 @@
}
}
function ensureDirtyIsSetIfAnyVariantIsDirty() {
$scope.contentForm.$dirty = false;
for (var i = 0; i < $scope.content.variants.length; i++) {
if($scope.content.variants[i].isDirty){
$scope.contentForm.$dirty = true;
return;
}
}
}
// This is a helper method to reduce the amount of code repitition for actions: Save, Publish, SendToPublish
function performSave(args) {
@@ -331,6 +343,7 @@
eventsService.emit("content.saved", { content: $scope.content, action: args.action });
resetNestedFieldValiation(fieldsToRollback);
ensureDirtyIsSetIfAnyVariantIsDirty();
return $q.when(data);
},

View File

@@ -136,7 +136,7 @@ angular.module('umbraco.directives')
return;
}
angularHelper.safeApply(scope, attrs.onOutsideClick);
scope.$apply(attrs.onOutsideClick);
}

View File

@@ -55,7 +55,7 @@ angular.module("umbraco.directives")
//initialize the standard editor functionality for Umbraco
tinyMceService.initializeEditor({
editor: editor,
value: scope.value,
model: scope,
currentForm: angularHelper.getCurrentForm(scope)
});
@@ -67,7 +67,7 @@ angular.module("umbraco.directives")
$timeout(function () {
if (scope.value === null) {
editor.trigger("focus");
editor.focus();
}
}, 400);

View File

@@ -0,0 +1,6 @@
angular.module('umbraco.filters')
.filter('safe_html', ['$sce', function($sce){
return function(text) {
return $sce.trustAsHtml(text);
};
}]);

View File

@@ -1194,7 +1194,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
.css("top", "auto")
.css("margin-top", "0")
.css("width", tinyMceWidth);
}
}
},
@@ -1214,15 +1214,15 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
if (!args.editor) {
throw "args.editor is required";
}
//if (!args.value) {
// throw "args.value is required";
//if (!args.model.value) {
// throw "args.model.value is required";
//}
var unwatch = null;
//Starts a watch on the model value so that we can update TinyMCE if the model changes behind the scenes or from the server
function startWatch() {
unwatch = $rootScope.$watch(() => args.value, function (newVal, oldVal) {
unwatch = $rootScope.$watch(() => args.model.value, function (newVal, oldVal) {
if (newVal !== oldVal) {
//update the display val again if it has changed from the server;
//uses an empty string in the editor when the value is null
@@ -1247,7 +1247,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
//stop watching before we update the value
stopWatch();
angularHelper.safeApply($rootScope, function () {
args.value = args.editor.getContent();
args.model.value = args.editor.getContent();
});
//re-watch the value
startWatch();
@@ -1255,8 +1255,8 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
args.editor.on('init', function (e) {
if (args.value) {
args.editor.setContent(args.value);
if (args.model.value) {
args.editor.setContent(args.model.value);
}
//enable browser based spell checking
args.editor.getBody().setAttribute('spellcheck', true);

View File

@@ -28,7 +28,8 @@
.umb-toggle__toggle {
cursor: pointer;
display: inline-block;
align-items: center;
display: flex;
width: 48px;
height: 24px;
background: @gray-8;
@@ -41,6 +42,11 @@
background-color: @green;
}
.umb-toggle--disabled .umb-toggle__toggle {
cursor: not-allowed;
opacity: 0.8;
}
.umb-toggle--checked .umb-toggle__handler {
transform: translate3d(24px, 0, 0) rotate(0);
}
@@ -63,7 +69,7 @@
.umb-toggle__icon {
position: absolute;
top: 3px;
line-height: 1em;
text-decoration: none;
transition: all 0.2s ease;
}

View File

@@ -19,6 +19,7 @@
align-items: center;
justify-content: center;
height: @editorHeaderHeight;
position: relative;
}
.umb-sub-views-nav-item:focus {
@@ -46,6 +47,33 @@
margin-bottom: 7px;
}
.umb-sub-views-nav-item .badge {
position: absolute;
top: 6px;
right: 6px;
min-width: 16px;
color: @white;
background-color: @turquoise-d1;
border: 2px solid @white;
border-radius: 50%;
font-size: 10px;
font-weight: bold;
padding: 2px;
line-height: 16px;
display: block;
&.-type-alert {
background-color: @red-l1;
}
&.-type-warning {
background-color: @yellow-d2;
}
&:empty {
height: 12px;
min-width: 12px;
}
}
.umb-sub-views-nav-item-text {
font-size: 12px;
line-height: 1em;
@@ -80,4 +108,4 @@
grid-template-columns: 1fr 1fr 1fr;
min-width: auto;
margin-top: 10px;
}
}

View File

@@ -4,10 +4,6 @@
padding: 7px 0;
}
.umb-permission--disabled {
opacity: 0.8;
}
.umb-permission:last-of-type {
border-bottom: none;
}
@@ -25,6 +21,12 @@
cursor: pointer;
}
.umb-permission--disabled .umb-permission__toggle,
.umb-permission--disabled .umb-permission__content {
cursor: not-allowed;
opacity: 0.8;
}
.umb-permission__description {
font-size: 13px;
color: @gray-4;

View File

@@ -1,4 +1,4 @@
<button ng-click="click()" type="button" class="umb-toggle" ng-class="{'umb-toggle--checked': checked}">
<button ng-click="click()" type="button" class="umb-toggle" ng-disabled="disabled" ng-class="{'umb-toggle--checked': checked, 'umb-toggle--disabled': disabled}">
<span ng-if="!labelPosition && showLabels === 'true' || labelPosition === 'left' && showLabels === 'true'">
<span ng-if="!checked" class="umb-toggle__label umb-toggle__label--left">{{ displayLabelOff }}</span>

View File

@@ -12,6 +12,7 @@
ng-class="{'is-active': item.active, '-has-error': item.hasError}">
<i class="icon {{ item.icon }}"></i>
<span class="umb-sub-views-nav-item-text">{{ item.name }}</span>
<div ng-show="item.badge" class="badge -type-{{item.badge.type}}">{{item.badge.count}}</div>
</a>
</div>
</li>

View File

@@ -19,7 +19,7 @@
<!-- Controls -->
<div ng-repeat="control in area.controls" class="dash-control dash-control-{{control.alias}}">
<div class="dash-inner-control">
<div ng-bind-html="control.html"></div>
<div ng-bind-html="control.html | safe_html"></div>
</div>
</div>
<!-- Controls end -->
@@ -65,7 +65,7 @@
</div>
</div>
</div>
</div>
</div>

View File

@@ -39,7 +39,8 @@
<div class="umb-permission" ng-click="vm.toggleDefault()" ng-class="{'umb-permission--disabled': vm.initIsDefault}">
<umb-toggle
class="umb-permission__toggle"
checked="vm.language.isDefault">
checked="vm.language.isDefault"
disabled="vm.initIsDefault">
</umb-toggle>
<div class="umb-permission__content" >
<div>{{vm.labels.defaultLanguage}}</div>

View File

@@ -13,7 +13,8 @@
hide-icon="true"
hide-description="true"
hide-alias="true"
navigation="content.apps">
navigation="content.apps"
on-select-navigation-item="appChanged(app)">
</umb-editor-header>
<umb-editor-container>

View File

@@ -95,8 +95,11 @@ function mediaEditController($scope, $routeParams, $q, appState, mediaResource,
function init() {
// set first app to active
$scope.content.apps[0].active = true;
if (!$scope.app) {
// set first app to active
$scope.content.apps[0].active = true;
$scope.app = $scope.content.apps[0];
}
// setup infinite mode
if(infiniteMode) {
@@ -207,6 +210,10 @@ function mediaEditController($scope, $routeParams, $q, appState, mediaResource,
}
};
$scope.appChanged = function (app) {
$scope.app = app;
}
evts.push(eventsService.on("editors.mediaType.saved", function(name, args) {
// if this media item uses the updated media type we need to reload the media item
if(args && args.mediaType && args.mediaType.key === $scope.content.contentType.key) {

View File

@@ -58,7 +58,7 @@ angular.module("umbraco")
//initialize the standard editor functionality for Umbraco
tinyMceService.initializeEditor({
editor: editor,
value: $scope.model.value,
model: $scope.model,
currentForm: angularHelper.getCurrentForm($scope)
});

View File

@@ -95,8 +95,8 @@
<PackageReference Include="Microsoft.AspNet.Mvc" Version="5.2.6" />
<PackageReference Include="Microsoft.AspNet.WebApi" Version="5.2.6" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.10.0" />
<PackageReference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" Version="2.0.0" />
<PackageReference Include="Microsoft.Net.Compilers" Version="2.9.0">
<PackageReference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" Version="2.0.1" />
<PackageReference Include="Microsoft.Net.Compilers" Version="2.10.0">
<PrivateAssets>all</PrivateAssets>
<!-- development dependency -->
</PackageReference>
@@ -107,7 +107,7 @@
<PackageReference Include="MySql.Data" Version="6.10.7" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Umbraco.ModelsBuilder.Ui">
<Version>8.0.0-alpha.26</Version>
<Version>8.0.0-alpha.31</Version>
</PackageReference>
<PackageReference Include="Umbraco.SqlServerCE" Version="4.0.0.1" />
</ItemGroup>
@@ -164,13 +164,6 @@
<Compile Include="Umbraco\Developer\Packages\DirectoryBrowser.aspx.designer.cs">
<DependentUpon>directoryBrowser.aspx</DependentUpon>
</Compile>
<Compile Include="Umbraco\Dialogs\ChangeDocType.aspx.cs">
<DependentUpon>ChangeDocType.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Umbraco\Dialogs\ChangeDocType.aspx.designer.cs">
<DependentUpon>ChangeDocType.aspx</DependentUpon>
</Compile>
<Compile Include="Umbraco\Masterpages\Default.Master.cs">
<DependentUpon>default.Master</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
@@ -294,15 +287,6 @@
<Content Include="Umbraco\Config\Lang\pt.xml" />
<Content Include="Umbraco\Config\Lang\ru.xml" />
<Content Include="Umbraco\Config\Lang\zh.xml" />
<Content Include="Umbraco\Developer\RelationTypes\EditRelationType.aspx" />
<Content Include="Umbraco\Developer\RelationTypes\Images\Bidirectional.png" />
<Content Include="Umbraco\Developer\RelationTypes\Images\ParentToChild.png" />
<Content Include="Umbraco\Developer\RelationTypes\Images\Refresh.gif" />
<Content Include="Umbraco\Developer\RelationTypes\NewRelationType.aspx" />
<Content Include="Umbraco\Developer\RelationTypes\RelationTypesWebService.asmx" />
<Content Include="Umbraco\Dialogs\ChangeDocType.aspx">
<SubType>ASPXCodeBehind</SubType>
</Content>
<Content Include="Umbraco\Config\Lang\ko.xml" />
<Content Include="Umbraco\Dashboard\FeedProxy.aspx" />
<Content Include="default.aspx" />
@@ -316,7 +300,6 @@
<Content Include="Umbraco\Config\Lang\nl.xml" />
<Content Include="Umbraco\Config\Lang\nb.xml" />
<Content Include="Umbraco\Config\Lang\sv.xml" />
<Content Include="Umbraco\Dialogs\republish.aspx" />
<Content Include="Umbraco\Developer\Packages\directoryBrowser.aspx" />
<Content Include="Umbraco\Developer\Packages\editPackage.aspx" />
<Content Include="Umbraco\Config\Create\UI.xml" />

View File

@@ -118,7 +118,7 @@
on-login="hideLoginScreen()">
</umb-login>
@Html.BareMinimumServerVariablesScript(Url, Url.Action("ExternalLogin", "BackOffice", new { area = ViewBag.UmbracoPath }), Model.Features, Current.Config.Global())
@Html.BareMinimumServerVariablesScript(Url, Url.Action("ExternalLogin", "BackOffice", new { area = ViewBag.UmbracoPath }), Model.Features, Current.Configs.Global())
<script>

View File

@@ -1,147 +0,0 @@
<%@ Page Language="C#" AutoEventWireup="true" Inherits="umbraco.cms.presentation.developer.RelationTypes.EditRelationType" MasterPageFile="../../masterpages/umbracoPage.Master" %>
<%@ Register TagPrefix="umb" Namespace="Umbraco.Web._Legacy.Controls" Assembly="Umbraco.Web" %>
<asp:Content ID="headContent" ContentPlaceHolderID="head" runat="server">
<style type="text/css">
table.relations { }
table.relations th { width:auto; }
table.relations th.objectTypeIcon { width:20px; }
table.relations th.directionIcon { width:16px; height:16px; }
table.relations td { background: transparent none no-repeat scroll center center }
table.relations td a { text-decoration: underline; }
/* objectType icons */
table.relations td.ContentItemType {}
table.relations td.ROOT {}
table.relations td.Document {}
table.relations td.Media {}
table.relations td.MemberType {}
table.relations td.Template {}
table.relations td.MemberGroup {}
table.relations td.ContentItem {}
table.relations td.MediaType {}
table.relations td.DocumentType {}
table.relations td.RecycleBin {}
table.relations td.Stylesheet {}
table.relations td.Member {}
table.relations td.DataType {}
/* direction icons */
table.relations td.parentToChild { background-image: url('../../developer/RelationTypes/Images/ParentToChild.png'); }
table.relations td.bidirectional { background-image: url('../../developer/RelationTypes/Images/Bidirectional.png'); }
</style>
</asp:Content>
<asp:Content ID="bodyContent" ContentPlaceHolderID="body" runat="server">
<umb:TabView runat="server" ID="tabControl" Width="200" />
<umb:Pane ID="idPane" runat="server" Text="">
<umb:PropertyPanel runat="server" id="idPropertyPanel" Text="Id">
<asp:Literal ID="idLiteral" runat="server" />
</umb:PropertyPanel>
</umb:Pane>
<umb:Pane ID="nameAliasPane" runat="server" Text="">
<umb:PropertyPanel runat="server" ID="nameProperyPanel" Text="Name">
<asp:TextBox ID="nameTextBox" runat="server" Columns="40" ></asp:TextBox>
<asp:RequiredFieldValidator ID="nameRequiredFieldValidator" runat="server" ControlToValidate="nameTextBox" ValidationGroup="RelationType" ErrorMessage="Name Required" Display="Dynamic" />
</umb:PropertyPanel>
<umb:PropertyPanel runat="server" id="aliasPropertyPanel" Text="Alias">
<asp:TextBox ID="aliasTextBox" runat="server" Columns="40"></asp:TextBox>
<asp:RequiredFieldValidator ID="aliasRequiredFieldValidator" runat="server" ControlToValidate="aliasTextBox" ValidationGroup="RelationType" ErrorMessage="Alias Required" Display="Dynamic" />
<asp:CustomValidator ID="aliasCustomValidator" runat="server" ControlToValidate="aliasTextBox" ValidationGroup="RelationType" onservervalidate="AliasCustomValidator_ServerValidate" ErrorMessage="Duplicate Alias" Display="Dynamic" />
</umb:PropertyPanel>
</umb:Pane>
<umb:Pane ID="directionPane" runat="server" Text="">
<umb:PropertyPanel runat="server" id="dualPropertyPanel" Text="Direction">
<asp:RadioButtonList ID="dualRadioButtonList" runat="server" RepeatDirection="Vertical">
<asp:ListItem Enabled="true" Selected="False" Text="Parent to Child" Value="0" />
<asp:ListItem Enabled="true" Selected="False" Text="Bidirectional" Value="1"/>
</asp:RadioButtonList>
</umb:PropertyPanel>
</umb:Pane>
<umb:Pane ID="objectTypePane" runat="server" Text="">
<umb:PropertyPanel runat="server" id="parentPropertyPanel" Text="Parent">
<asp:Literal ID="parentLiteral" runat="server" />
</umb:PropertyPanel>
<umb:PropertyPanel runat="server" id="childPropertyPanel" Text="Child">
<asp:Literal ID="childLiteral" runat="server" />
</umb:PropertyPanel>
</umb:Pane>
<umb:Pane ID="relationsCountPane" runat="server" Text="">
<umb:PropertyPanel runat="server" id="relationsCountPropertyPanel" Text="Count">
<asp:Literal ID="relationsCountLiteral" runat="server" />
</umb:PropertyPanel>
</umb:Pane>
<umb:Pane ID="relationsPane" runat="server" Text="">
<umb:PropertyPanel runat="server" id="relationsPropertyPanel" Text="Relations">
<asp:Repeater ID="relationsRepeater" runat="server">
<HeaderTemplate>
<table class="table relations">
<thead>
<tr>
<th class="objectTypeIcon">&nbsp;</th>
<th>Parent</th>
<th class="directionIcon">&nbsp;</th>
<th class="objectTypeIcon">&nbsp;</th>
<th>Child</th>
<th>Created</th>
<th>Comment</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td class="<%= this.ParentObjectType %>">&nbsp;</td>
<td><a href="<%# GetEditUrl(this.ParentObjectType, (int)DataBinder.Eval(Container.DataItem, "ParentId")) %>" target="_blank"><%# DataBinder.Eval(Container.DataItem, "ParentText") %></a></td>
<td class="<%= this.RelationTypeDirection %>">&nbsp;</td>
<td class="<%= this.ChildObjectType %>">&nbsp;</td>
<td><a href="<%# GetEditUrl(this.ChildObjectType, (int)DataBinder.Eval(Container.DataItem, "ChildId")) %>" target="_blank"><%# DataBinder.Eval(Container.DataItem, "ChildText") %></a></td>
<td><%# DataBinder.Eval(Container.DataItem, "DateTime") %></td>
<td><%# DataBinder.Eval(Container.DataItem, "Comment") %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
</umb:PropertyPanel>
</umb:Pane>
</asp:Content>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,50 +0,0 @@
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="NewRelationType.aspx.cs" Inherits="umbraco.cms.presentation.developer.RelationTypes.NewRelationType" MasterPageFile="../../masterpages/umbracoDialog.Master"%>
<%@ Register TagPrefix="umb" Namespace="Umbraco.Web._Legacy.Controls" Assembly="Umbraco.Web" %>
<asp:Content ID="bodyContent" ContentPlaceHolderID="body" runat="server">
<umb:Pane ID="nameAliasPane" runat="server" Text="">
<umb:PropertyPanel runat="server" ID="nameProperyPanel" Text="Name">
<asp:TextBox ID="descriptionTextBox" runat="server" Columns="40" AutoCompleteType="Disabled" style="width:200px;" />
<asp:RequiredFieldValidator ID="descriptionRequiredFieldValidator" runat="server" ControlToValidate="descriptionTextBox" ValidationGroup="NewRelationType" ErrorMessage="Name Required" Display="Dynamic" />
</umb:PropertyPanel>
<umb:PropertyPanel runat="server" id="aliasPropertyPanel" Text="Alias">
<asp:TextBox ID="aliasTextBox" runat="server" Columns="40" AutoCompleteType="Disabled" style="width:200px;" />
<asp:RequiredFieldValidator ID="aliasRequiredFieldValidator" runat="server" ControlToValidate="aliasTextBox" ValidationGroup="NewRelationType" ErrorMessage="Alias Required" Display="Dynamic" />
<asp:CustomValidator ID="aliasCustomValidator" runat="server" ControlToValidate="aliasTextBox" ValidationGroup="NewRelationType" onservervalidate="AliasCustomValidator_ServerValidate" ErrorMessage="Duplicate Alias" Display="Dynamic" />
</umb:PropertyPanel>
</umb:Pane>
<umb:Pane ID="directionPane" runat="server" Text="">
<umb:PropertyPanel runat="server" id="PropertyPanel1" Text="Direction">
<asp:RadioButtonList ID="dualRadioButtonList" runat="server" RepeatDirection="Horizontal">
<asp:ListItem Enabled="true" Selected="True" Text="Parent to Child" Value="0"/>
<asp:ListItem Enabled="true" Selected="False" Text="Bidirectional" Value="1"/>
</asp:RadioButtonList>
</umb:PropertyPanel>
</umb:Pane>
<umb:Pane ID="objectTypePane" runat="server" Text="">
<umb:PropertyPanel runat="server" id="PropertyPanel2" Text="Parent">
<asp:DropDownList ID="parentDropDownList" runat="server" />
</umb:PropertyPanel>
<umb:PropertyPanel runat="server" id="PropertyPanel3" Text="Child">
<asp:DropDownList ID="childDropDownList" runat="server" />
</umb:PropertyPanel>
</umb:Pane>
<umb:Pane runat="server" CssClass="btn-toolbar umb-btn-toolbar">
<a href="#" class="btn btn-link" onclick="UmbClientMgr.closeModalWindow()"><%=Services.TextService.Localize("cancel")%></a>
<asp:Button ID="addButton" runat="server" Text="Create" cssclass="btn btn-primary" onclick="AddButton_Click" CausesValidation="true" ValidationGroup="NewRelationType" />
</umb:Pane>
</asp:Content>

View File

@@ -1 +0,0 @@
<%@ WebService Language="C#" CodeBehind="RelationTypesWebService.asmx.cs" Class="umbraco.cms.presentation.developer.RelationTypes.RelationTypesWebService" %>

View File

@@ -1,120 +0,0 @@
<%@ Page Language="c#" MasterPageFile="../masterpages/umbracoDialog.Master"Codebehind="ChangeDocType.aspx.cs" AutoEventWireup="True" Inherits="Umbraco.Web.UI.Umbraco.Dialogs.ChangeDocType" %>
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" Assembly="Umbraco.Web" %>
<asp:Content ContentPlaceHolderID="head" runat="server">
<style type="text/css">
#propertyMapping thead tr th{border-bottom:1px solid #ccc; padding: 4px; padding-right: 25px;
background-image: url(<%= Umbraco.Core.IO.IOHelper.ResolveUrl(Umbraco.Core.IO.SystemDirectories.UmbracoClient) %>/tableSorting/img/bg.gif);
cursor: pointer;
font-weight: bold;
background-repeat: no-repeat;
background-position: center right;
}
#propertyMapping tbody tr td{border-bottom:1px solid #efefef}
#propertyMapping td{padding: 4px; ;}
body.umbracoDialog { overflow: auto; }
.umb-dialog .umb-control-group .umb-el-wrap { overflow: hidden; }
.umb-dialog .umb-control-group .umb-el-wrap label { float: left; width: 140px; font-weight: bold; }
.umb-dialog .umb-control-group .umb-el-wrap label:after { content:":"; }
.umb-dialog .umb-control-group .umb-el-wrap .controls-row { float: left; width: 280px; padding-bottom: 8px; }
.umb-dialog .umb-control-group .umb-el-wrap .controls-row select { width: auto; }
</style>
</asp:Content>
<asp:Content ContentPlaceHolderID="body" runat="server">
<cc1:Pane runat="server" ID="ChangeDocTypePane">
<p class="help">
<%= Services.TextService.Localize("changeDocType/changeDocTypeInstruction") %>
</p>
<cc1:PropertyPanel ID="ContentNamePropertyPanel" runat="server">
<asp:Label ID="ContentNameLabel" runat="server" />
</cc1:PropertyPanel>
<cc1:PropertyPanel ID="CurrentTypePropertyPanel" runat="server">
<asp:Label ID="CurrentTypeLabel" runat="server" />
</cc1:PropertyPanel>
<cc1:PropertyPanel ID="NewTypePropertyPanel" runat="server">
<asp:DropDownList ID="NewDocumentTypeList" runat="server" AutoPostBack="true" OnSelectedIndexChanged="NewDocumentTypeList_SelectedIndexChanged" />
<asp:RequiredFieldValidator ControlToValidate="NewDocumentTypeList" ErrorMessage="*" ID="NewDocumentTypeValidator" runat="server" Display="Dynamic" />
<br /><small><%=Services.TextService.Localize("changeDocType/validDocTypesNote") %></small>
</cc1:PropertyPanel>
<cc1:PropertyPanel ID="NewTemplatePropertyPanel" runat="server">
<asp:DropDownList ID="NewTemplateList" runat="server" />
</cc1:PropertyPanel>
<asp:PlaceHolder ID="NotAvailablePlaceholder" runat="server" Visible="false">
<div class="propertyItem notice" style="padding-top: 10px">
<p><%=Services.TextService.Localize("changeDocType/docTypeCannotBeChanged") %></p>
</div>
</asp:PlaceHolder>
</cc1:Pane>
<cc1:Pane runat="server" ID="ChangeDocTypePropertyMappingPane">
<p class="help">
<%= Services.TextService.Localize("changeDocType/changeDocTypeInstruction2") %>
</p>
<asp:Repeater ID="PropertyMappingRepeater" runat="server">
<HeaderTemplate>
<table id="propertyMapping">
<thead>
<tr>
<th><%= Services.TextService.Localize("changeDocType/currentProperty") %></th>
<th><%= Services.TextService.Localize("changeDocType/mapToProperty") %></th>
</tr>
</thead>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<%# DataBinder.Eval(Container, "DataItem.Name") %>
<asp:HiddenField ID="Alias" runat="server" Value='<%#DataBinder.Eval(Container, "DataItem.Alias")%>' />
<asp:HiddenField ID="Name" runat="server" Value='<%#DataBinder.Eval(Container, "DataItem.Name")%>' />
<asp:HiddenField ID="PropertyEditorAlias" runat="server" Value='<%#DataBinder.Eval(Container, "DataItem.PropertyEditorAlias")%>' />
</td>
<td><asp:DropDownList id="DestinationProperty" runat="server" /></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</cc1:Pane>
<asp:PlaceHolder ID="SuccessPlaceholder" runat="server" Visible="false">
<p><%=Services.TextService.Localize("changeDocType/docTypeChanged") %></p>
<p>
<asp:Literal ID="SuccessMessage" runat="server" />
<asp:Literal ID="PropertiesMappedMessage" runat="server" />
<asp:Literal ID="ContentPublishedMessage" runat="server" />
<br /><br />
<a href="#" style="color: blue" onclick="UmbClientMgr.closeModalWindow()"><%=Services.TextService.Localize("defaultdialogs/closeThisWindow") %></a>
</p>
</asp:PlaceHolder>
<asp:PlaceHolder ID="ValidationPlaceholder" runat="server" Visible="false">
<br />
<div class="notice" style="padding: 10px">
<asp:Literal id="ValidationError" runat="server" />
</div>
</asp:PlaceHolder>
<div class="btn-toolbar umb-btn-toolbar">
<asp:PlaceHolder ID="SaveAndCancelPlaceholder" runat="server">
<a href="#" class="btn btn-link" onclick="UmbClientMgr.closeModalWindow()"><%=Services.TextService.Localize("general/cancel")%></a>
<asp:PlaceHolder ID="SavePlaceholder" runat="server">
<asp:Button ID="ValidateAndSave" runat="server" CssClass="btn btn-primary" Text="Create" OnClick="ValidateAndSave_Click"></asp:Button>
</asp:PlaceHolder>
</asp:Placeholder>
</div>
</asp:Content>

View File

@@ -1,346 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using Umbraco.Core;
using Umbraco.Core.Services;
using Umbraco.Core.Models;
using Umbraco.Web.UI.Pages;
namespace Umbraco.Web.UI.Umbraco.Dialogs
{
public partial class ChangeDocType : UmbracoEnsuredPage
{
class PropertyMapping
{
public string FromName { get; set; }
public string ToName { get; set; }
public string ToAlias { get; set; }
public object Value { get; set; }
}
private IContent _content;
protected void Page_Load(object sender, EventArgs e)
{
var contentNodeId = int.Parse(Request.QueryString["id"]);
_content = Services.ContentService.GetById(contentNodeId);
LocalizeTexts();
if (!Page.IsPostBack)
{
DisplayContentDetails();
if (PopulateListOfValidAlternateDocumentTypes())
{
PopulateListOfTemplates();
PopulatePropertyMappingWithSources();
PopulatePropertyMappingWithDestinations();
}
else
{
DisplayNotAvailable();
}
}
}
private void LocalizeTexts()
{
ChangeDocTypePane.Text = Services.TextService.Localize("changeDocType/selectNewDocType");
ContentNamePropertyPanel.Text = Services.TextService.Localize("changeDocType/selectedContent");
CurrentTypePropertyPanel.Text = Services.TextService.Localize("changeDocType/currentType");
NewTypePropertyPanel.Text = Services.TextService.Localize("changeDocType/newType");
NewTemplatePropertyPanel.Text = Services.TextService.Localize("changeDocType/newTemplate");
ChangeDocTypePropertyMappingPane.Text = Services.TextService.Localize("changeDocType/mapProperties");
ValidateAndSave.Text = Services.TextService.Localize("buttons/save");
}
private void DisplayContentDetails()
{
ContentNameLabel.Text = _content.Name;
CurrentTypeLabel.Text = _content.ContentType.Name;
}
private bool PopulateListOfValidAlternateDocumentTypes()
{
// Start with all content types
var documentTypes = Services.ContentTypeService.GetAll().ToArray();
// Remove invalid ones from list of potential alternatives
documentTypes = RemoveCurrentDocumentTypeFromAlternatives(documentTypes).ToArray();
documentTypes = RemoveInvalidByParentDocumentTypesFromAlternatives(documentTypes).ToArray();
documentTypes = RemoveInvalidByChildrenDocumentTypesFromAlternatives(documentTypes).ToArray();
// If we have at least one, bind to list and return true
if (documentTypes.Any())
{
NewDocumentTypeList.DataSource = documentTypes.OrderBy(x => x.Name);
NewDocumentTypeList.DataValueField = "Id";
NewDocumentTypeList.DataTextField = "Name";
NewDocumentTypeList.DataBind();
return true;
}
return false;
}
private IEnumerable<IContentType> RemoveCurrentDocumentTypeFromAlternatives(IEnumerable<IContentType> documentTypes)
{
return documentTypes
.Where(x => x.Id != _content.ContentType.Id);
}
private IEnumerable<IContentType> RemoveInvalidByParentDocumentTypesFromAlternatives(IEnumerable<IContentType> documentTypes)
{
if (_content.ParentId == -1)
{
// Root content, only include those that have been selected as allowed at root
return documentTypes
.Where(x => x.AllowedAsRoot);
}
else
{
// Below root, so only include those allowed as sub-nodes for the parent
var parentNode = Services.ContentService.GetById(_content.ParentId);
return documentTypes
.Where(x => parentNode.ContentType.AllowedContentTypes
.Select(y => y.Id.Value)
.Contains(x.Id));
}
}
private IEnumerable<IContentType> RemoveInvalidByChildrenDocumentTypesFromAlternatives(IEnumerable<IContentType> documentTypes)
{
//fixme Should do proper paging here ... when this is refactored we will
var docTypeIdsOfChildren = Services.ContentService.GetPagedChildren(_content.Id, 0, int.MaxValue, out var total)
.Select(x => x.ContentType.Id)
.Distinct()
.ToList();
return documentTypes
.Where(x => x.AllowedContentTypes
.Select(y => y.Id.Value)
.ContainsAll(docTypeIdsOfChildren));
}
private void PopulateListOfTemplates()
{
// Get selected new document type
var contentType = GetSelectedDocumentType();
// Populate template list
NewTemplateList.DataSource = contentType.AllowedTemplates;
NewTemplateList.DataValueField = "Id";
NewTemplateList.DataTextField = "Name";
NewTemplateList.DataBind();
NewTemplateList.Items.Add(new ListItem("<" + Services.TextService.Localize("changeDocType/none") + ">", "0"));
// Set default template
if (contentType.DefaultTemplate != null)
{
var itemToSelect = NewTemplateList.Items.FindByValue(contentType.DefaultTemplate.Id.ToString());
if (itemToSelect != null)
{
itemToSelect.Selected = true;
}
}
}
private void PopulatePropertyMappingWithSources()
{
PropertyMappingRepeater.DataSource = GetPropertiesOfContentType(_content.ContentType);
PropertyMappingRepeater.DataBind();
}
private void PopulatePropertyMappingWithDestinations()
{
// Get selected new document type
var contentType = GetSelectedDocumentType();
// Get properties of new document type (including any from parent types)
var properties = GetPropertiesOfContentType(contentType);
// Loop through list of source properties and populate destination options with all those of same property type
foreach (RepeaterItem ri in PropertyMappingRepeater.Items)
{
if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem)
{
// Get data type from hidden field
var propEdAlias = ((HiddenField)ri.FindControl("PropertyEditorAlias")).Value;
// Bind destination list with properties that match data type
var ddl = (DropDownList)ri.FindControl("DestinationProperty");
ddl.DataSource = properties.Where(x => x.PropertyEditorAlias == propEdAlias);
ddl.DataValueField = "Alias";
ddl.DataTextField = "Name";
ddl.DataBind();
ddl.Items.Insert(0, new ListItem("<" + Services.TextService.Localize("changeDocType/none") + ">", string.Empty));
// Set default selection to be one with matching alias
var alias = ((HiddenField)ri.FindControl("Alias")).Value;
var item = ddl.Items.FindByValue(alias);
if (item != null)
{
item.Selected = true;
}
}
}
}
private IContentType GetSelectedDocumentType()
{
return Services.ContentTypeService.Get(int.Parse(NewDocumentTypeList.SelectedItem.Value));
}
private IEnumerable<PropertyType> GetPropertiesOfContentType(IContentType contentType)
{
return contentType.CompositionPropertyTypes;
}
private void DisplayNotAvailable()
{
NewTypePropertyPanel.Visible = false;
NewTemplatePropertyPanel.Visible = false;
SavePlaceholder.Visible = false;
NotAvailablePlaceholder.Visible = true;
ChangeDocTypePropertyMappingPane.Visible = false;
}
protected void NewDocumentTypeList_SelectedIndexChanged(object sender, EventArgs e)
{
PopulateListOfTemplates();
PopulatePropertyMappingWithDestinations();
}
protected void ValidateAndSave_Click(object sender, EventArgs e)
{
if (IsPropertyMappingValid())
{
// For all properties to be mapped, save the values to a temporary list
var propertyMappings = SavePropertyMappings();
// Get flag for if content already published
var wasPublished = _content.Published;
// Change the document type passing flag to clear the properties
var newContentType = GetSelectedDocumentType();
_content.ChangeContentType(newContentType, true);
// Set the template if one has been selected
if (NewTemplateList.SelectedItem != null)
{
var templateId = int.Parse(NewTemplateList.SelectedItem.Value);
_content.Template = templateId > 0 ? Services.FileService.GetTemplate(templateId) : null;
}
// Set the property values
var propertiesMappedMessageBuilder = new StringBuilder("<ul>");
foreach (var propertyMapping in propertyMappings)
{
propertiesMappedMessageBuilder.AppendFormat("<li>{0} {1} {2}</li>",
propertyMapping.FromName, Services.TextService.Localize("changeDocType/to"), propertyMapping.ToName);
_content.SetValue(propertyMapping.ToAlias, propertyMapping.Value);
}
propertiesMappedMessageBuilder.Append("</ul>");
// Save
var user = Security.CurrentUser;
Services.ContentService.Save(_content, user.Id);
// Publish if the content was already published
if (wasPublished)
{
// no values to publish, really
Services.ContentService.SaveAndPublish(_content, userId: user.Id);
}
// Sync the tree
ClientTools.SyncTree(_content.Path, true);
// Reload the page if the content was already being viewed
ClientTools.ReloadLocation();
// Display success message
SuccessMessage.Text = Services.TextService.Localize("changeDocType/successMessage").Replace("[new type]", "<strong>" + newContentType.Name + "</strong>");
PropertiesMappedMessage.Text = propertiesMappedMessageBuilder.ToString();
if (wasPublished)
{
ContentPublishedMessage.Text = Services.TextService.Localize("changeDocType/contentRepublished");
ContentPublishedMessage.Visible = true;
}
else
{
ContentPublishedMessage.Visible = false;
}
SuccessPlaceholder.Visible = true;
SaveAndCancelPlaceholder.Visible = false;
ValidationPlaceholder.Visible = false;
ChangeDocTypePane.Visible = false;
ChangeDocTypePropertyMappingPane.Visible = false;
}
else
{
ValidationPlaceholder.Visible = true;
}
}
private bool IsPropertyMappingValid()
{
// Check whether any properties have been mapped to more than once
var mappedPropertyAliases = new List<string>();
foreach (RepeaterItem ri in PropertyMappingRepeater.Items)
{
if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem)
{
var ddl = (DropDownList)ri.FindControl("DestinationProperty");
var mappedPropertyAlias = ddl.SelectedItem.Value;
if (!string.IsNullOrEmpty(mappedPropertyAlias))
{
if (mappedPropertyAliases.Contains(mappedPropertyAlias))
{
ValidationError.Text = Services.TextService.Localize("changeDocType/validationErrorPropertyWithMoreThanOneMapping");
return false;
}
mappedPropertyAliases.Add(mappedPropertyAlias);
}
}
}
return true;
}
private IList<PropertyMapping> SavePropertyMappings()
{
// Create list of mapped property values for assignment after the document type is changed
var mappedPropertyValues = new List<PropertyMapping>();
foreach (RepeaterItem ri in PropertyMappingRepeater.Items)
{
if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem)
{
// Get property alias to map to
var ddl = (DropDownList)ri.FindControl("DestinationProperty");
var mappedAlias = ddl.SelectedItem.Value;
if (!string.IsNullOrEmpty(mappedAlias))
{
// If mapping property, get current property value from alias
var sourceAlias = ((HiddenField)ri.FindControl("Alias")).Value;
var sourcePropertyValue = _content.GetValue(sourceAlias);
// Add to list
mappedPropertyValues.Add(new PropertyMapping
{
FromName = ((HiddenField)ri.FindControl("Name")).Value,
ToName = ddl.SelectedItem.Text,
ToAlias = mappedAlias,
Value = sourcePropertyValue
});
}
}
}
return mappedPropertyValues;
}
}
}

View File

@@ -1,213 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Umbraco.Web.UI.Umbraco.Dialogs {
public partial class ChangeDocType {
/// <summary>
/// ChangeDocTypePane control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::Umbraco.Web._Legacy.Controls.Pane ChangeDocTypePane;
/// <summary>
/// ContentNamePropertyPanel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::Umbraco.Web._Legacy.Controls.PropertyPanel ContentNamePropertyPanel;
/// <summary>
/// ContentNameLabel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Label ContentNameLabel;
/// <summary>
/// CurrentTypePropertyPanel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::Umbraco.Web._Legacy.Controls.PropertyPanel CurrentTypePropertyPanel;
/// <summary>
/// CurrentTypeLabel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Label CurrentTypeLabel;
/// <summary>
/// NewTypePropertyPanel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::Umbraco.Web._Legacy.Controls.PropertyPanel NewTypePropertyPanel;
/// <summary>
/// NewDocumentTypeList control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.DropDownList NewDocumentTypeList;
/// <summary>
/// NewDocumentTypeValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator NewDocumentTypeValidator;
/// <summary>
/// NewTemplatePropertyPanel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::Umbraco.Web._Legacy.Controls.PropertyPanel NewTemplatePropertyPanel;
/// <summary>
/// NewTemplateList control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.DropDownList NewTemplateList;
/// <summary>
/// NotAvailablePlaceholder control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.PlaceHolder NotAvailablePlaceholder;
/// <summary>
/// ChangeDocTypePropertyMappingPane control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::Umbraco.Web._Legacy.Controls.Pane ChangeDocTypePropertyMappingPane;
/// <summary>
/// PropertyMappingRepeater control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Repeater PropertyMappingRepeater;
/// <summary>
/// SuccessPlaceholder control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.PlaceHolder SuccessPlaceholder;
/// <summary>
/// SuccessMessage control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal SuccessMessage;
/// <summary>
/// PropertiesMappedMessage control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal PropertiesMappedMessage;
/// <summary>
/// ContentPublishedMessage control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal ContentPublishedMessage;
/// <summary>
/// ValidationPlaceholder control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.PlaceHolder ValidationPlaceholder;
/// <summary>
/// ValidationError control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal ValidationError;
/// <summary>
/// SaveAndCancelPlaceholder control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.PlaceHolder SaveAndCancelPlaceholder;
/// <summary>
/// SavePlaceholder control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.PlaceHolder SavePlaceholder;
/// <summary>
/// ValidateAndSave control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button ValidateAndSave;
}
}

View File

@@ -1,41 +0,0 @@
<%@ Page Language="c#" Codebehind="republish.aspx.cs" MasterPageFile="../masterpages/umbracoDialog.Master" AutoEventWireup="True" Inherits="umbraco.cms.presentation.republish" %>
<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" Assembly="Umbraco.Web" %>
<asp:Content ContentPlaceHolderID="head" runat="server">
<script type="text/javascript">
function showProgress(button, elementId) {
var img = document.getElementById(elementId);
img.style.visibility = "visible";
button.style.display = "none";
}
</script>
</asp:Content>
<asp:Content ContentPlaceHolderID="body" runat="server">
<asp:Panel ID="p_republish" runat="server">
<div class="propertyDiv">
<p><%= Services.TextService.Localize("defaultdialogs/siterepublishHelp")%> </p>
</div>
<div id="buttons" class="btn-toolbar umb-btn-toolbar">
<a href="#" class="btn btn-link" onclick="UmbClientMgr.closeModalWindow();"><%=Services.TextService.Localize("cancel")%></a>
<asp:Button ID="bt_go" cssclass="btn btn-primary" OnClick="go" OnClientClick="showProgress(document.getElementById('buttons'),'progress'); return true;" runat="server" Text="Republish" />
</div>
<div id="progress" style="visibility: hidden;">
<div class="umb-loader-wrapper">
<cc1:ProgressBar ID="progbar" runat="server" Title="Please wait..." />
</div>
</div>
</asp:Panel>
<asp:Panel ID="p_done" Visible="false" runat="server">
<div class="success">
<p><%= Services.TextService.Localize("defaultdialogs/siterepublished")%></p>
</div>
<input type="button" class="btn btn-primary" onclick="UmbClientMgr.closeModalWindow();" value="Ok" />
</asp:Panel>
</asp:Content>

View File

@@ -299,11 +299,11 @@
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4"
compilerOptions="/langversion:7 /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4"
compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
</compilers>

Some files were not shown because too many files have changed in this diff Show More