diff --git a/src/Umbraco.Core/ApplicationContext.cs b/src/Umbraco.Core/ApplicationContext.cs
index db905be43f..8c7f62f980 100644
--- a/src/Umbraco.Core/ApplicationContext.cs
+++ b/src/Umbraco.Core/ApplicationContext.cs
@@ -1,114 +1,105 @@
using System;
using System.Configuration;
using System.Threading;
-using System.Threading.Tasks;
-using System.Web;
-using System.Web.Caching;
-using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
-using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
-using Umbraco.Core.Profiling;
using Umbraco.Core.Services;
using Umbraco.Core.Sync;
namespace Umbraco.Core
{
///
- /// the Umbraco Application context
+ /// Represents the Umbraco application context.
///
- ///
- /// one per AppDomain, represents the global Umbraco application
- ///
+ /// Only one singleton instance per running Umbraco application (AppDomain)
public class ApplicationContext : IDisposable
{
+ private volatile bool _disposed;
+ private readonly ReaderWriterLockSlim _disposalLocker = new ReaderWriterLockSlim();
+ private bool _isReady;
+ readonly ManualResetEventSlim _isReadyEvent = new ManualResetEventSlim(false);
+ private DatabaseContext _databaseContext;
+ private ServiceContext _services;
+ private Lazy _configured;
+
+ // ReSharper disable once InconsistentNaming
+ internal string _umbracoApplicationUrl;
+
///
- /// Constructor
+ /// Initializes a new instance of the class.
///
- ///
- ///
- ///
- ///
+ /// A database context.
+ /// A service context.
+ /// A cache helper.
+ /// A logger.
public ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, ProfilingLogger logger)
{
- if (dbContext == null) throw new ArgumentNullException("dbContext");
- if (serviceContext == null) throw new ArgumentNullException("serviceContext");
- if (cache == null) throw new ArgumentNullException("cache");
- if (logger == null) throw new ArgumentNullException("logger");
+ if (dbContext == null) throw new ArgumentNullException(nameof(dbContext));
+ if (serviceContext == null) throw new ArgumentNullException(nameof(serviceContext));
+ if (cache == null) throw new ArgumentNullException(nameof(cache));
+ if (logger == null) throw new ArgumentNullException(nameof(logger));
+
_databaseContext = dbContext;
_services = serviceContext;
ApplicationCache = cache;
ProfilingLogger = logger;
- Init();
+ Initialize();
}
- ///
- /// Creates a basic app context
- ///
- ///
- ///
- public ApplicationContext(CacheHelper cache, ProfilingLogger logger)
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A cache helper.
+ /// A logger.
+ /// For Unit Tests only.
+ public ApplicationContext(CacheHelper cache, ProfilingLogger logger)
{
- if (cache == null) throw new ArgumentNullException("cache");
- if (logger == null) throw new ArgumentNullException("logger");
+ if (cache == null) throw new ArgumentNullException(nameof(cache));
+ if (logger == null) throw new ArgumentNullException(nameof(logger));
+
ApplicationCache = cache;
ProfilingLogger = logger;
- Init();
+
+ Initialize();
}
///
- /// A method used to set and/or ensure that a global ApplicationContext singleton is created.
+ /// Sets and/or ensures that a global application context exists.
///
- ///
- /// The instance to set on the global application singleton
- ///
- /// If set to true and the singleton is already set, it will be replaced
- ///
- ///
- /// This is NOT thread safe
- ///
+ /// The application context instance.
+ /// A value indicating whether to replace the existing context, if any.
+ /// The current global application context.
+ /// This is NOT thread safe. For Unit Tests only.
public static ApplicationContext EnsureContext(ApplicationContext appContext, bool replaceContext)
{
- if (Current != null)
- {
- if (!replaceContext)
- return Current;
- }
- Current = appContext;
- return Current;
+ if (Current != null && replaceContext == false)
+ return Current;
+
+ return Current = appContext;
}
- ///
- /// A method used to create and ensure that a global ApplicationContext singleton is created.
- ///
- ///
- ///
- ///
- /// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
- /// startup if for some reason the boot manager is not the umbraco boot manager.
- ///
- ///
- ///
- ///
- ///
- /// This is NOT thread safe
- ///
+ ///
+ /// Sets and/or ensures that a global application context exists.
+ ///
+ /// A cache helper.
+ /// A logger.
+ /// A database context.
+ /// A service context.
+ /// A value indicating whether to replace the existing context, if any.
+ /// The current global application context.
+ /// This is NOT thread safe. For Unit Tests only.
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, ProfilingLogger logger, bool replaceContext)
{
- if (Current != null)
- {
- if (!replaceContext)
+ if (Current != null && replaceContext == false)
return Current;
- }
- var ctx = new ApplicationContext(dbContext, serviceContext, cache, logger);
- Current = ctx;
- return Current;
+
+ return Current = new ApplicationContext(dbContext, serviceContext, cache, logger);
}
///
- /// Singleton accessor
+ /// Gets the current global application context.
///
public static ApplicationContext Current { get; internal set; }
@@ -121,20 +112,30 @@ namespace Umbraco.Core
public CacheHelper ApplicationCache { get; private set; }
///
- /// Exposes the global ProfilingLogger - this should generally not be accessed via the UmbracoContext and should normally just be exposed
- /// on most base classes or injected with IoC
+ /// Gets the profiling logger.
///
- public ProfilingLogger ProfilingLogger { get; private set; }
+ public ProfilingLogger ProfilingLogger { get; }
- // IsReady is set to true by the boot manager once it has successfully booted
- // note - the original umbraco module checks on content.Instance in umbraco.dll
- // now, the boot task that setup the content store ensures that it is ready
- bool _isReady = false;
- readonly ManualResetEventSlim _isReadyEvent = new ManualResetEventSlim(false);
- private DatabaseContext _databaseContext;
- private ServiceContext _services;
+ ///
+ /// Gets the MainDom.
+ ///
+ internal MainDom MainDom { get; private set; }
- public bool IsReady
+ ///
+ /// Gets a value indicating whether the application is configured.
+ ///
+ /// Meaning: installed and no need to upgrade anything.
+ public virtual bool IsConfigured => _configured.Value;
+
+ ///
+ /// Gets a value indicating whether the application is ready.
+ ///
+ /// Meaning: ready to run, boot has completed, though maybe the application is not configured.
+ /// IsReady is set to true by the boot manager once it has successfully booted. The original
+ /// Umbraco module checked on content.Instance, now the boot task that sets the content
+ /// store ensures that it is ready.
+ ///
+ public bool IsReady
{
get
{
@@ -142,50 +143,49 @@ namespace Umbraco.Core
}
internal set
{
- AssertIsNotReady();
- _isReady = value;
+ if (IsReady)
+ throw new Exception("ApplicationContext has already been initialized.");
+ if (value == false)
+ throw new Exception("Value must be true.");
+
+ _isReady = true;
_isReadyEvent.Set();
}
}
+ ///
+ /// Blocks until the application is ready.
+ ///
+ /// The time to wait, or -1 to wait indefinitely.
+ /// A value indicating whether the application is ready.
public bool WaitForReady(int timeout)
{
return _isReadyEvent.WaitHandle.WaitOne(timeout);
}
-
- // notes
- // GlobalSettings.ConfigurationStatus returns the value that's in the web.config, so it's the "configured version"
- // GlobalSettings.CurrentVersion returns the hard-coded "current version"
- // the system is configured if they match
- // if they don't, install runs, updates web.config (presumably) and updates GlobalSettings.ConfiguredStatus
-
- public bool IsConfigured
- {
- get { return _configured.Value; }
- }
-
- ///
- /// If the db is configured, there is a database context and there is an umbraco schema, but we are not 'configured' , then it means we are upgrading
+ ///
+ /// Gets a value indicating whether the application is upgrading.
///
+ /// Meaning: the database is configured and the database context has access to an existing Umbraco schema,
+ /// however we are not 'configured' because we still need to upgrade.
public bool IsUpgrading
{
get
{
- if (IsConfigured == false
- && DatabaseContext != null
- && DatabaseContext.IsDatabaseConfigured)
- {
- var schemaresult = DatabaseContext.ValidateDatabaseSchema();
- if (schemaresult.ValidTables.Count > 0) return true;
- }
+ if (IsConfigured // configured already
+ || DatabaseContext == null // no database context
+ || DatabaseContext.IsDatabaseConfigured == false // database is not configured
+ || DatabaseContext.CanConnect == false) // database cannot connect
+ return false;
- return false;
+ // upgrading if we have some valid tables (else, no schema, need to install)
+ var schemaresult = DatabaseContext.ValidateDatabaseSchema();
+ return schemaresult.ValidTables.Count > 0;
}
}
///
- /// The application url.
+ /// Gets the application Url.
///
///
/// The application url is the url that should be used by services to talk to the application,
@@ -215,64 +215,63 @@ namespace Umbraco.Core
}
}
- // ReSharper disable once InconsistentNaming
- internal string _umbracoApplicationUrl;
-
- private Lazy _configured;
- internal MainDom MainDom { get; private set; }
-
- private void Init()
+ private void Initialize()
{
MainDom = new MainDom(ProfilingLogger.Logger);
MainDom.Acquire();
-
- //Create the lazy value to resolve whether or not the application is 'configured'
+
+ ResetConfigured();
+ }
+
+ ///
+ /// Resets the IsConfigured value, which will then be discovered again.
+ ///
+ /// For Unit Tests usage, though it is harmless.
+ public void ResetConfigured()
+ {
+ // create the lazy value to resolve whether or not the application is 'configured'
+ // meaning: installed and no need to upgrade anything
_configured = new Lazy(() =>
{
try
{
- var configStatus = ConfigurationStatus;
- var currentVersion = UmbracoVersion.GetSemanticVersion();
+ var configStatus = ConfigurationStatus; // the value in the web.config
+ var currentVersion = UmbracoVersion.GetSemanticVersion(); // the hard-coded current version of the binaries that are executing
- var ok =
- //we are not configured if this is null
- string.IsNullOrWhiteSpace(configStatus) == false
- //they must match
- && configStatus == currentVersion;
-
- if (ok)
+ // if we have no value in web.config or value differs, we are not configured yet
+ if (string.IsNullOrWhiteSpace(configStatus) || configStatus != currentVersion)
{
- //The versions are the same in config, but are they the same in the database. We can only check this
- // if we have a db context available, if we don't then we are not installed anyways
- if (DatabaseContext.IsDatabaseConfigured && DatabaseContext.CanConnect)
- {
- var found = Services.MigrationEntryService.FindEntry(GlobalSettings.UmbracoMigrationName, UmbracoVersion.GetSemanticVersion());
- if (found == null)
- {
- //we haven't executed this migration in this environment, so even though the config versions match,
- // this db has not been updated.
- ProfilingLogger.Logger.Debug(string.Format("The migration for version: '{0} has not been executed, there is no record in the database", currentVersion.ToSemanticString()));
- ok = false;
- }
- }
- }
- else
- {
- ProfilingLogger.Logger.Debug(string.Format("CurrentVersion different from configStatus: '{0}','{1}'", currentVersion.ToSemanticString(), configStatus));
+ ProfilingLogger.Logger.Debug($"CurrentVersion different from configStatus: '{currentVersion.ToSemanticString()}','{configStatus}'.");
+ return false;
}
- return ok;
+ // versions match, now look for database state and migrations
+ // which requires that we do have a database that we can connect to
+ if (DatabaseContext.IsDatabaseConfigured == false || DatabaseContext.CanConnect == false)
+ {
+ ProfilingLogger.Logger.Debug("Database is not configured, or could not connect to the database.");
+ return false;
+ }
+
+ // look for a migration entry for the current version
+ var entry = Services.MigrationEntryService.FindEntry(GlobalSettings.UmbracoMigrationName, UmbracoVersion.GetSemanticVersion());
+ if (entry != null)
+ return true; // all clear!
+
+ // even though the versions match, the db has not been properly upgraded
+ ProfilingLogger.Logger.Debug($"The migration for version: '{currentVersion.ToSemanticString()} has not been executed, there is no record in the database.");
+ return false;
}
catch (Exception ex)
{
- LogHelper.Error("Error determining if application is configured, returning false", ex);
+ LogHelper.Error("Error determining if application is configured, returning false.", ex);
return false;
}
+ });
+ }
- });
- }
-
- private string ConfigurationStatus
+ // gets the configuration status, ie the version that's in web.config
+ private string ConfigurationStatus
{
get
{
@@ -282,102 +281,91 @@ namespace Umbraco.Core
}
catch
{
- return String.Empty;
+ return string.Empty;
}
- }
+ }
}
- private void AssertIsNotReady()
- {
- if (this.IsReady)
- throw new Exception("ApplicationContext has already been initialized.");
- }
-
///
- /// Gets the current DatabaseContext
+ /// Gets the current database context.
///
- ///
- /// Internal set is generally only used for unit tests
- ///
public DatabaseContext DatabaseContext
{
get
{
if (_databaseContext == null)
- throw new InvalidOperationException("The DatabaseContext has not been set on the ApplicationContext");
+ throw new InvalidOperationException("The DatabaseContext has not been set on the ApplicationContext.");
return _databaseContext;
}
+ // INTERNAL FOR UNIT TESTS
internal set { _databaseContext = value; }
}
-
+
///
- /// Gets the current ServiceContext
+ /// Gets the current service context.
///
- ///
- /// Internal set is generally only used for unit tests
- ///
public ServiceContext Services
{
get
{
if (_services == null)
- throw new InvalidOperationException("The ServiceContext has not been set on the ApplicationContext");
+ throw new InvalidOperationException("The ServiceContext has not been set on the ApplicationContext.");
return _services;
}
- internal set { _services = value; }
+ // INTERNAL FOR UNIT TESTS
+ internal set { _services = value; }
}
+ ///
+ /// Gets the server role.
+ ///
+ ///
internal ServerRole GetCurrentServerRole()
{
var registrar = ServerRegistrarResolver.Current.Registrar as IServerRegistrar2;
- return registrar == null ? ServerRole.Unknown : registrar.GetCurrentServerRole();
+ return registrar?.GetCurrentServerRole() ?? ServerRole.Unknown;
}
- private volatile bool _disposed;
- private readonly ReaderWriterLockSlim _disposalLocker = new ReaderWriterLockSlim();
-
///
- /// This will dispose and reset all resources used to run the application
+ /// Disposes the application context.
///
- ///
- /// IMPORTANT: Never dispose this object if you require the Umbraco application to run, disposing this object
+ /// Do not this object if you require the Umbraco application to run. Disposing this object
/// is generally used for unit testing and when your application is shutting down after you have booted Umbraco.
///
void IDisposable.Dispose()
{
- // Only operate if we haven't already disposed
if (_disposed) return;
using (new WriteLock(_disposalLocker))
{
- // Check again now we're inside the lock
+ // double check... bah...
if (_disposed) return;
- //clear the cache
+ // clear the cache
if (ApplicationCache != null)
{
ApplicationCache.RuntimeCache.ClearAllCache();
ApplicationCache.IsolatedRuntimeCache.ClearAllCaches();
}
- //reset all resolvers
+
+ // reset all resolvers
ResolverCollection.ResetAll();
- //reset resolution itself (though this should be taken care of by resetting any of the resolvers above)
+
+ // reset resolution itself (though this should be taken care of by resetting any of the resolvers above)
Resolution.Reset();
-
- //reset the instance objects
- this.ApplicationCache = null;
+
+ // reset the instance objects
+ ApplicationCache = null;
if (_databaseContext != null) //need to check the internal field here
{
- if (DatabaseContext.IsDatabaseConfigured && DatabaseContext.Database != null)
- {
- DatabaseContext.Database.Dispose();
- }
+ if (DatabaseContext.IsDatabaseConfigured)
+ DatabaseContext.Database?.Dispose();
}
- this.DatabaseContext = null;
- this.Services = null;
- this._isReady = false; //set the internal field
-
- // Indicate that the instance has been disposed.
+
+ DatabaseContext = null;
+ Services = null;
+ _isReady = false; //set the internal field
+
_disposed = true;
}
}
diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs
index c77f3f2002..11034023a0 100644
--- a/src/Umbraco.Core/DatabaseContext.cs
+++ b/src/Umbraco.Core/DatabaseContext.cs
@@ -63,7 +63,7 @@ namespace Umbraco.Core
/// This should not be used for CRUD operations or queries against the
/// standard Umbraco tables! Use the Public services for that.
///
- public virtual UmbracoDatabase Database => _factory.GetDatabase();
+ public UmbracoDatabase Database => _factory.GetDatabase();
///
/// Gets a value indicating whether the database is configured, ie whether it exists
@@ -75,7 +75,7 @@ namespace Umbraco.Core
///
/// Gets a value indicating whether it is possible to connect to the database.
///
- public virtual bool CanConnect
+ public bool CanConnect
{
get
{
diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RemoveMasterContentTypeColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RemoveMasterContentTypeColumn.cs
index ab423a8e34..e21cab814f 100644
--- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RemoveMasterContentTypeColumn.cs
+++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RemoveMasterContentTypeColumn.cs
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix
public override void Up()
{
//NOTE Don't think we can remove this column yet as it seems to be used by some starterkits
- IfDatabase(DatabaseType.SQLCe, DatabaseType.SqlServer2005)
+ IfDatabase(DatabaseType.SQLCe, DatabaseType.SqlServer2008)
.Delete.DefaultConstraint().OnTable("cmsContentType").OnColumn("masterContentType");
Delete.Column("masterContentType").FromTable("cmsContentType");
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviders.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviders.cs
deleted file mode 100644
index f5e118e653..0000000000
--- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviders.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Umbraco.Core.Logging;
-
-namespace Umbraco.Core.Persistence.SqlSyntax
-{
- // fixme - this exists ONLY for unit tests at the moment!
- public sealed class SqlSyntaxProviders
- {
- public static IEnumerable GetDefaultProviders(ILogger logger)
- {
- return new ISqlSyntaxProvider[]
- {
- new MySqlSyntaxProvider(logger),
- new SqlCeSyntaxProvider(),
- new SqlServerSyntaxProvider(new Lazy(() => null))
- };
- }
- }
-}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs
index 9ad14529f6..50c89aedb7 100644
--- a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs
+++ b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs
@@ -79,6 +79,17 @@ namespace Umbraco.Core.Persistence
EnableSqlTrace = false;
}
+ // INTERNAL FOR UNIT TESTS
+ internal UmbracoDatabase(DbConnection connection,
+ ISqlSyntaxProvider sqlSyntax, DatabaseType databaseType, DbProviderFactory provider,
+ ILogger logger)
+ : base(connection, databaseType, provider, DefaultIsolationLevel)
+ {
+ SqlSyntax = sqlSyntax;
+ _logger = logger;
+ EnableSqlTrace = false;
+ }
+
// fixme: that could be an extension method of IUmbracoDatabaseConfig
public Sql Sql()
{
diff --git a/src/Umbraco.Core/Persistence/UnitOfWork/NPocoUnitOfWorkProvider.cs b/src/Umbraco.Core/Persistence/UnitOfWork/NPocoUnitOfWorkProvider.cs
index d6ac4cc36f..17e05dc3ed 100644
--- a/src/Umbraco.Core/Persistence/UnitOfWork/NPocoUnitOfWorkProvider.cs
+++ b/src/Umbraco.Core/Persistence/UnitOfWork/NPocoUnitOfWorkProvider.cs
@@ -1,4 +1,6 @@
-using Umbraco.Core.Configuration;
+using System;
+using System.Collections.Generic;
+using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -31,9 +33,22 @@ namespace Umbraco.Core.Persistence.UnitOfWork
/// with the default connection name, and default sql syntax providers.
///
internal NPocoUnitOfWorkProvider(ILogger logger)
- : this(new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName, SqlSyntaxProviders.GetDefaultProviders(logger), logger))
+ : this(new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName, GetDefaultSqlSyntaxProviders(logger), logger))
{ }
+ // this should NOT be here, all tests should supply the appropriate providers,
+ // however the above ctor is used in hundreds of tests at the moment, so...
+ // will refactor later
+ private static IEnumerable GetDefaultSqlSyntaxProviders(ILogger logger)
+ {
+ return new ISqlSyntaxProvider[]
+ {
+ new MySqlSyntaxProvider(logger),
+ new SqlCeSyntaxProvider(),
+ new SqlServerSyntaxProvider(new Lazy(() => null))
+ };
+ }
+
#region Implement IUnitOfWorkProvider
///
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 5c4591e4df..0ed691e96e 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -1043,7 +1043,6 @@
-
diff --git a/src/Umbraco.Tests/ApplicationContextTests.cs b/src/Umbraco.Tests/ApplicationContextTests.cs
index 61dabf6e3b..b27b496fbb 100644
--- a/src/Umbraco.Tests/ApplicationContextTests.cs
+++ b/src/Umbraco.Tests/ApplicationContextTests.cs
@@ -11,6 +11,7 @@ using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Profiling;
using Umbraco.Core.Services;
+using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests
{
@@ -26,15 +27,15 @@ namespace Umbraco.Tests
migrationEntryService.Setup(x => x.FindEntry(It.IsAny(), It.IsAny()))
.Returns(Mock.Of());
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
- dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(true);
- dbCtx.Setup(x => x.CanConnect).Returns(true);
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock();
+ var logger = Mock.Of();
+ var dbCtx = new Mock(databaseFactory, logger);
var appCtx = new ApplicationContext(
dbCtx.Object,
- new ServiceContext(migrationEntryService:migrationEntryService.Object),
+ new ServiceContext(migrationEntryService:migrationEntryService.Object),
CacheHelper.CreateDisabledCacheHelper(),
- new ProfilingLogger(Mock.Of(), Mock.Of()));
+ new ProfilingLogger(logger, Mock.Of()));
Assert.IsTrue(appCtx.IsConfigured);
}
@@ -48,15 +49,15 @@ namespace Umbraco.Tests
migrationEntryService.Setup(x => x.FindEntry(It.IsAny(), It.IsAny()))
.Returns((IMigrationEntry)null);
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
- dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(true);
- dbCtx.Setup(x => x.CanConnect).Returns(true);
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock();
+ var logger = Mock.Of();
+ var dbCtx = new Mock(databaseFactory, logger);
var appCtx = new ApplicationContext(
dbCtx.Object,
new ServiceContext(migrationEntryService: migrationEntryService.Object),
CacheHelper.CreateDisabledCacheHelper(),
- new ProfilingLogger(Mock.Of(), Mock.Of()));
+ new ProfilingLogger(logger, Mock.Of()));
Assert.IsFalse(appCtx.IsConfigured);
}
@@ -68,15 +69,15 @@ namespace Umbraco.Tests
var migrationEntryService = new Mock();
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
- dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(true);
- dbCtx.Setup(x => x.CanConnect).Returns(true);
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock();
+ var logger = Mock.Of();
+ var dbCtx = new Mock(databaseFactory, logger);
var appCtx = new ApplicationContext(
dbCtx.Object,
new ServiceContext(migrationEntryService: migrationEntryService.Object),
CacheHelper.CreateDisabledCacheHelper(),
- new ProfilingLogger(Mock.Of(), Mock.Of()));
+ new ProfilingLogger(logger, Mock.Of()));
Assert.IsFalse(appCtx.IsConfigured);
}
@@ -88,9 +89,9 @@ namespace Umbraco.Tests
var migrationEntryService = new Mock();
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
- dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(false);
- dbCtx.Setup(x => x.CanConnect).Returns(true);
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock(false);
+ var logger = Mock.Of();
+ var dbCtx = new Mock(databaseFactory, logger);
var appCtx = new ApplicationContext(
dbCtx.Object,
@@ -108,9 +109,9 @@ namespace Umbraco.Tests
var migrationEntryService = new Mock();
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
- dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(true);
- dbCtx.Setup(x => x.CanConnect).Returns(false);
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock(true, false);
+ var logger = Mock.Of();
+ var dbCtx = new Mock(databaseFactory, logger);
var appCtx = new ApplicationContext(
dbCtx.Object,
diff --git a/src/Umbraco.Tests/Migrations/Upgrades/ValidateV7UpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/ValidateV7UpgradeTest.cs
index c21da772b6..31494ec8a3 100644
--- a/src/Umbraco.Tests/Migrations/Upgrades/ValidateV7UpgradeTest.cs
+++ b/src/Umbraco.Tests/Migrations/Upgrades/ValidateV7UpgradeTest.cs
@@ -46,7 +46,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
[Test]
public void Validate_AddIndexToCmsMacroPropertyTable()
{
- var migration = new AddIndexToCmsMacroTable(true, _logger);
+ var migration = new AddIndexToCmsMacroPropertyTable(true, _logger);
var migrationContext = new MigrationContext(_database, _logger);
migration.GetUpExpressions(migrationContext);
diff --git a/src/Umbraco.Tests/MockTests.cs b/src/Umbraco.Tests/MockTests.cs
index 353923ec30..3b4f72aa4e 100644
--- a/src/Umbraco.Tests/MockTests.cs
+++ b/src/Umbraco.Tests/MockTests.cs
@@ -39,25 +39,30 @@ namespace Umbraco.Tests
[Test]
public void Can_Create_Service_Context()
{
- var svcCtx = MockHelper.GetMockedServiceContext();
+ var svcCtx = TestObjects.GetServiceContextMock();
Assert.Pass();
}
[Test]
public void Can_Create_Db_Context()
{
- var dbCtx = new DatabaseContext(new Mock().Object, Mock.Of());
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock();
+ var logger = Mock.Of();
+ var dbCtx = new DatabaseContext(databaseFactory, logger);
Assert.Pass();
}
[Test]
public void Can_Create_App_Context_With_Services()
{
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock();
+ var logger = Mock.Of();
+
var appCtx = new ApplicationContext(
- new DatabaseContext(new Mock().Object, Mock.Of()),
- MockHelper.GetMockedServiceContext(),
+ new DatabaseContext(databaseFactory, logger),
+ TestObjects.GetServiceContextMock(),
CacheHelper.CreateDisabledCacheHelper(),
- new ProfilingLogger(Mock.Of(), Mock.Of()));
+ new ProfilingLogger(logger, Mock.Of()));
Assert.Pass();
}
diff --git a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs
index 6839d6f2c6..50df11aea4 100644
--- a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs
+++ b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs
@@ -43,9 +43,11 @@ namespace Umbraco.Tests.Models.Mapping
var nullCacheHelper = CacheHelper.CreateDisabledCacheHelper();
var logger = Mock.Of();
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock();
+
//Create an app context using mocks
var appContext = new ApplicationContext(
- new DatabaseContext(Mock.Of(), logger),
+ new DatabaseContext(databaseFactory, logger),
//Create service context using mocks
new ServiceContext(
diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs
index 40063cdd8b..3d1e4a268e 100644
--- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs
+++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs
@@ -33,28 +33,12 @@ namespace Umbraco.Tests.Persistence
_logger = Mock.Of();
var dbFactory = new DefaultDatabaseFactory(Core.Configuration.GlobalSettings.UmbracoConnectionName, _sqlSyntaxProviders, _logger);
_dbContext = new DatabaseContext(dbFactory, _logger);
-
- // unfortunately we have to set this up because the NPocoExtensions require singleton access
- // fixme - there is no need for this!
- /*
- ApplicationContext.Current = new ApplicationContext(
- CacheHelper.CreateDisabledCacheHelper(),
- new ProfilingLogger(Mock.Of(), Mock.Of()))
- {
- DatabaseContext = _dbContext,
- IsReady = true
- };
- */
}
[TearDown]
public void TearDown()
{
_dbContext = null;
- // fixme - no need
- /*
- ApplicationContext.Current = null;
- */
}
[Test]
@@ -95,7 +79,7 @@ namespace Umbraco.Tests.Persistence
engine.CreateDatabase();
// re-create the database factory and database context with proper connection string
- var dbFactory = new DefaultDatabaseFactory(engine.LocalConnectionString, _sqlSyntaxProviders, _logger);
+ var dbFactory = new DefaultDatabaseFactory(engine.LocalConnectionString, Constants.DbProviderNames.SqlCe, _sqlSyntaxProviders, _logger);
_dbContext = new DatabaseContext(dbFactory, _logger);
// create application context
diff --git a/src/Umbraco.Tests/Persistence/Migrations/MigrationStartupHandlerTests.cs b/src/Umbraco.Tests/Persistence/Migrations/MigrationStartupHandlerTests.cs
index ed2bbb20d9..a59a500ac6 100644
--- a/src/Umbraco.Tests/Persistence/Migrations/MigrationStartupHandlerTests.cs
+++ b/src/Umbraco.Tests/Persistence/Migrations/MigrationStartupHandlerTests.cs
@@ -17,6 +17,7 @@ using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Profiling;
using Umbraco.Core.Services;
+using Umbraco.Tests.TestHelpers;
using Umbraco.Web.Strategies.Migrations;
namespace Umbraco.Tests.Persistence.Migrations
@@ -24,53 +25,18 @@ namespace Umbraco.Tests.Persistence.Migrations
[TestFixture]
public class MigrationStartupHandlerTests
{
- // NPoco wants a DbConnection and NOT an IDbConnection
- // and DbConnection is hard to mock...
- private class MockConnection : DbConnection
- {
- protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
- {
- return Mock.Of(); // enough here
- }
-
- public override void Close()
- {
- throw new NotImplementedException();
- }
-
- public override void ChangeDatabase(string databaseName)
- {
- throw new NotImplementedException();
- }
-
- public override void Open()
- {
- throw new NotImplementedException();
- }
-
- public override string ConnectionString { get; set; }
-
- protected override DbCommand CreateDbCommand()
- {
- throw new NotImplementedException();
- }
-
- public override string Database { get; }
- public override string DataSource { get; }
- public override string ServerVersion { get; }
- public override ConnectionState State => ConnectionState.Open; // else NPoco reopens
- }
-
[Test]
public void Executes_For_Any_Product_Name_When_Not_Specified()
{
+ var logger = Mock.Of();
+
var changed1 = new Args { CountExecuted = 0 };
var testHandler1 = new TestMigrationHandler(changed1);
- testHandler1.OnApplicationStarting(Mock.Of(), new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of(), Mock.Of())));
+ testHandler1.OnApplicationStarting(Mock.Of(), new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(logger, Mock.Of())));
- var db = new UmbracoDatabase("cstr", new SqlCeSyntaxProvider(), DatabaseType.SQLCe, DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlCe), Mock.Of());
+ var db = TestObjects.GetUmbracoSqlCeDatabase(logger);
- var runner1 = new MigrationRunner(Mock.Of(), Mock.Of(), Mock.Of(), new SemVersion(1), new SemVersion(2), "Test1",
+ var runner1 = new MigrationRunner(Mock.Of(), Mock.Of(), logger, new SemVersion(1), new SemVersion(2), "Test1",
new IMigration[] { Mock.Of() });
var result1 = runner1.Execute(db /*, false*/);
Assert.AreEqual(1, changed1.CountExecuted);
@@ -79,22 +45,25 @@ namespace Umbraco.Tests.Persistence.Migrations
[Test]
public void Executes_Only_For_Specified_Product_Name()
{
+ var logger = Mock.Of();
+
var changed1 = new Args { CountExecuted = 0};
var testHandler1 = new TestMigrationHandler("Test1", changed1);
- testHandler1.OnApplicationStarting(Mock.Of(), new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of(), Mock.Of())));
+ testHandler1.OnApplicationStarting(Mock.Of(), new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(logger, Mock.Of())));
+
var changed2 = new Args { CountExecuted = 0 };
var testHandler2 = new TestMigrationHandler("Test2", changed2);
- testHandler2.OnApplicationStarting(Mock.Of(), new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of(), Mock.Of())));
+ testHandler2.OnApplicationStarting(Mock.Of(), new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(logger, Mock.Of())));
- var db = new UmbracoDatabase("cstr", new SqlCeSyntaxProvider(), DatabaseType.SQLCe, DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlCe), Mock.Of());
+ var db = TestObjects.GetUmbracoSqlCeDatabase(logger);
- var runner1 = new MigrationRunner(Mock.Of(), Mock.Of(), Mock.Of(), new SemVersion(1), new SemVersion(2), "Test1",
+ var runner1 = new MigrationRunner(Mock.Of(), Mock.Of(), logger, new SemVersion(1), new SemVersion(2), "Test1",
new IMigration[] { Mock.Of()});
var result1 = runner1.Execute(db /*, false*/);
Assert.AreEqual(1, changed1.CountExecuted);
Assert.AreEqual(0, changed2.CountExecuted);
- var runner2 = new MigrationRunner(Mock.Of(), Mock.Of(), Mock.Of(), new SemVersion(1), new SemVersion(2), "Test2",
+ var runner2 = new MigrationRunner(Mock.Of(), Mock.Of(), logger, new SemVersion(1), new SemVersion(2), "Test2",
new IMigration[] { Mock.Of() });
var result2 = runner2.Execute(db /*, false*/);
Assert.AreEqual(1, changed1.CountExecuted);
diff --git a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs
index ed06a5e003..72e58295a6 100644
--- a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs
+++ b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs
@@ -100,7 +100,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
{
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy(() => null));
var logger = Mock.Of();
- var db = new UmbracoDatabase("cstr", sqlSyntax, DatabaseType.SqlServer2005, DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlServer), logger);
+ var db = TestObjects.GetUmbracoSqlServerDatabase(logger);
var context = new MigrationContext(db, logger);
var createExpression = new CreateIndexExpression(context, new []{ DatabaseType.SqlServer2005 })
{
@@ -116,7 +116,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
{
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy(() => null));
var logger = Mock.Of();
- var db = new UmbracoDatabase("cstr", sqlSyntax, DatabaseType.SqlServer2005, DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlServer), logger);
+ var db = TestObjects.GetUmbracoSqlServerDatabase(logger);
var context = new MigrationContext(db, logger);
var createExpression = new CreateIndexExpression(context, new[] { DatabaseType.SqlServer2005 })
{
@@ -132,7 +132,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
{
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy(() => null));
var logger = Mock.Of();
- var db = new UmbracoDatabase("cstr", sqlSyntax, DatabaseType.SqlServer2005, DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlServer), logger);
+ var db = TestObjects.GetUmbracoSqlServerDatabase(logger);
var context = new MigrationContext(db, logger);
var createExpression = new CreateIndexExpression(context, new[] { DatabaseType.SqlServer2005 })
{
diff --git a/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs b/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs
index 18d4e1c080..fe17ea20da 100644
--- a/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs
+++ b/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs
@@ -35,7 +35,7 @@ namespace Umbraco.Tests.Routing
protected ServiceContext GetServiceContext(IUmbracoSettingsSection umbracoSettings, ILogger logger)
{
//get the mocked service context to get the mocked domain service
- var svcCtx = MockHelper.GetMockedServiceContext();
+ var svcCtx = TestObjects.GetServiceContextMock();
var domainService = Mock.Get(svcCtx.DomainService);
//setup mock domain service
@@ -60,8 +60,9 @@ namespace Umbraco.Tests.Routing
protected override void SetupApplicationContext()
{
var settings = SettingsForTests.GetDefault();
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock();
ApplicationContext.Current = new ApplicationContext(
- new DatabaseContext(Mock.Of(), Logger),
+ new DatabaseContext(databaseFactory, Logger),
GetServiceContext(settings, Logger),
CacheHelper,
ProfilingLogger)
diff --git a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs
index 320ab400d3..9536813b1c 100644
--- a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs
+++ b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs
@@ -28,19 +28,19 @@ namespace Umbraco.Tests.Security
//should force app ctx to show not-configured
ConfigurationManager.AppSettings.Set("umbracoConfigurationStatus", "");
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), Mock.Of(), "test");
- dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(false);
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock(false);
+ var dbCtx = new Mock(databaseFactory, Mock.Of());
var appCtx = new ApplicationContext(
dbCtx.Object,
- MockHelper.GetMockedServiceContext(),
+ TestObjects.GetServiceContextMock(),
CacheHelper.CreateDisabledCacheHelper(),
new ProfilingLogger(Mock.Of(), Mock.Of()));
-
+
var umbCtx = UmbracoContext.CreateContext(
- Mock.Of(),
- appCtx,
- new WebSecurity(Mock.Of(), appCtx),
+ Mock.Of(),
+ appCtx,
+ new WebSecurity(Mock.Of(), appCtx),
Mock.Of(), new List(), false);
var mgr = new BackOfficeCookieManager(Mock.Of(accessor => accessor.Value == umbCtx));
@@ -53,12 +53,12 @@ namespace Umbraco.Tests.Security
[Test]
public void ShouldAuthenticateRequest_When_Configured()
{
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), Mock.Of(), "test");
- dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(true);
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock();
+ var dbCtx = new Mock(databaseFactory, Mock.Of());
var appCtx = new ApplicationContext(
dbCtx.Object,
- MockHelper.GetMockedServiceContext(),
+ TestObjects.GetServiceContextMock(),
CacheHelper.CreateDisabledCacheHelper(),
new ProfilingLogger(Mock.Of(), Mock.Of()));
@@ -74,7 +74,7 @@ namespace Umbraco.Tests.Security
request.Setup(owinRequest => owinRequest.Uri).Returns(new Uri("http://localhost/umbraco"));
var result = mgr.ShouldAuthenticateRequest(
- Mock.Of(context => context.Request == request.Object),
+ Mock.Of(context => context.Request == request.Object),
new Uri("http://localhost/umbraco"));
Assert.IsTrue(result);
diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs
index 274b644738..ca965eaca0 100644
--- a/src/Umbraco.Tests/Services/ContentServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs
@@ -1333,7 +1333,7 @@ namespace Umbraco.Tests.Services
[Test]
public void Can_Save_Lazy_Content()
{
- var databaseFactory = new DefaultDatabaseFactory(Umbraco.Core.Configuration.GlobalSettings.UmbracoConnectionName, SqlSyntaxProviders.GetDefaultProviders(Logger), Logger);
+ var databaseFactory = new DefaultDatabaseFactory(Umbraco.Core.Configuration.GlobalSettings.UmbracoConnectionName, TestObjects.GetDefaultSqlSyntaxProviders(Logger), Logger);
var provider = new NPocoUnitOfWorkProvider(databaseFactory);
var unitOfWork = provider.GetUnitOfWork();
var contentType = ServiceContext.ContentTypeService.GetContentType("umbTextpage");
diff --git a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs b/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs
index 1b7037a601..bea1110155 100644
--- a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs
+++ b/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Configuration;
using System.Data.Common;
using System.Diagnostics;
using System.Linq;
@@ -81,9 +82,9 @@ namespace Umbraco.Tests.Services
_error = null;
// dispose!
- _dbFactory.Dispose();
+ _dbFactory?.Dispose();
- base.TearDown();
+ base.TearDown();
}
///
@@ -264,9 +265,10 @@ namespace Umbraco.Tests.Services
public UmbracoDatabase GetDatabase()
{
+ var settings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName];
return _databases.GetOrAdd(
Thread.CurrentThread.ManagedThreadId,
- i => new UmbracoDatabase(Core.Configuration.GlobalSettings.UmbracoConnectionName, SqlSyntax, DatabaseType, _dbProviderFactory, _logger));
+ i => new UmbracoDatabase(settings.ConnectionString, SqlSyntax, DatabaseType, _dbProviderFactory, _logger));
}
protected override void DisposeResources()
diff --git a/src/Umbraco.Tests/Templates/TemplateRepositoryTests.cs b/src/Umbraco.Tests/Templates/TemplateRepositoryTests.cs
index ece4a1a0fd..be0ee5d824 100644
--- a/src/Umbraco.Tests/Templates/TemplateRepositoryTests.cs
+++ b/src/Umbraco.Tests/Templates/TemplateRepositoryTests.cs
@@ -17,29 +17,29 @@ using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
+using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Templates
{
[TestFixture]
public class TemplateRepositoryTests
{
- private readonly Mock _unitOfWorkMock = new Mock();
private readonly Mock _cacheMock = new Mock();
- private TemplateRepository _templateRepository;
private readonly Mock _viewFileSystemMock = new Mock();
private readonly Mock _masterpageFileSystemMock = new Mock();
private readonly Mock _templateConfigMock = new Mock();
+ private TemplateRepository _templateRepository;
[SetUp]
public void Setup()
{
- var uowMock = new Mock();
- var db = new UmbracoDatabase("cstr", new SqlCeSyntaxProvider(), DatabaseType.SQLCe, DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlCe), Mock.Of());
- uowMock.Setup(x => x.Database).Returns(db);
+ var logger = Mock.Of();
- var loggerMock = new Mock();
+ var unitOfWorkMock = new Mock();
+ var db = TestObjects.GetUmbracoSqlCeDatabase(logger);
+ unitOfWorkMock.Setup(x => x.Database).Returns(db);
- _templateRepository = new TemplateRepository(_unitOfWorkMock.Object, _cacheMock.Object, loggerMock.Object, _masterpageFileSystemMock.Object, _viewFileSystemMock.Object, _templateConfigMock.Object, Mock.Of());
+ _templateRepository = new TemplateRepository(unitOfWorkMock.Object, _cacheMock.Object, logger, _masterpageFileSystemMock.Object, _viewFileSystemMock.Object, _templateConfigMock.Object, Mock.Of());
}
diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs
index b2b3b7f47a..34127d7560 100644
--- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs
+++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs
@@ -34,6 +34,8 @@ using Umbraco.Web.Routing;
using Umbraco.Web.Security;
using umbraco.BusinessLogic;
using Umbraco.Core.Events;
+using Umbraco.Core.Models;
+using File = System.IO.File;
namespace Umbraco.Tests.TestHelpers
{
@@ -89,44 +91,67 @@ namespace Umbraco.Tests.TestHelpers
{
var sqlSyntaxProviders = new[] { new SqlCeSyntaxProvider() };
- var dbFactory = new DefaultDatabaseFactory(
- GetDbConnectionString(),
- GetDbProviderName(),
- sqlSyntaxProviders,
- Logger);
+ // create the database if required
+ // note: must do before instanciating the database factory else it will
+ // not find the database and will remain un-configured.
+ using (ProfilingLogger.TraceDuration("Create database."))
+ {
+ //TODO make it faster
+ CreateSqlCeDatabase();
+ }
+
+ // ensure the configuration matches the current version for tests
+ SettingsForTests.ConfigurationStatus = UmbracoVersion.Current.ToString(3);
+
+ // create the database factory - if the test does not require an actual database,
+ // use a mock factory; otherwise use a real factory.
+ var databaseFactory = DatabaseTestBehavior == DatabaseBehavior.NoDatabasePerFixture
+ ? TestObjects.GetIDatabaseFactoryMock()
+ : new DefaultDatabaseFactory(GetDbConnectionString(), GetDbProviderName(), sqlSyntaxProviders, Logger);
+
+ // so, using the above code to create a mock IDatabaseFactory if we don't have a real database
+ // but, that will NOT prevent _appContext from NOT being configured, because it cannot connect
+ // to the database to check the migrations ;-(
var evtMsgs = new TransientMessagesFactory();
- _appContext = new ApplicationContext(
- //assign the db context
- new DatabaseContext(dbFactory, Logger),
- //assign the service context
- new ServiceContext(
- Container.GetInstance(),
- new NPocoUnitOfWorkProvider(dbFactory),
- new FileUnitOfWorkProvider(),
- new PublishingStrategy(evtMsgs, Logger),
- CacheHelper,
- Logger,
- evtMsgs,
- Enumerable.Empty()),
+ var databaseContext = new DatabaseContext(databaseFactory, Logger);
+ var serviceContext = new ServiceContext(
+ Container.GetInstance(),
+ new NPocoUnitOfWorkProvider(databaseFactory),
+ new FileUnitOfWorkProvider(),
+ new PublishingStrategy(evtMsgs, Logger),
CacheHelper,
- ProfilingLogger)
+ Logger,
+ evtMsgs,
+ Enumerable.Empty());
+
+ //var appContextMock = new Mock(databaseContext, serviceContext, CacheHelper, ProfilingLogger);
+ //// if the test does not require an actual database, or runs with an empty database, the application
+ //// context will not be able to check the migration status in the database, so we have to force it
+ //// to think it is configured.
+ //if (DatabaseTestBehavior == DatabaseBehavior.NoDatabasePerFixture // no db at all
+ // || DatabaseTestBehavior == DatabaseBehavior.EmptyDbFilePerTest) // empty db
+ // appContextMock.Setup(x => x.IsConfigured).Returns(true);
+ //_appContext = appContextMock.Object;
+ _appContext = new ApplicationContext(databaseContext, serviceContext, CacheHelper, ProfilingLogger);
+
+ // initialize the database if required
+ // note: must do after creating the application context as
+ // it is using it
+ using (ProfilingLogger.TraceDuration("Initialize database."))
{
- IsReady = true
- };
+ // TODO make it faster
+ InitializeDatabase(_appContext);
+ }
+
+ // ensure the application context understand we are configured now
+ SettingsForTests.ConfigurationStatus = UmbracoVersion.GetSemanticVersion().ToSemanticString();
+ _appContext.ResetConfigured();
+
+ // application is ready
+ _appContext.IsReady = true;
ApplicationContext.Current = _appContext;
-
- using (ProfilingLogger.TraceDuration("init"))
- {
- //TODO: Somehow make this faster - takes 5s +
-
- CreateSqlCeDatabase();
- InitializeDatabase();
-
- //ensure the configuration matches the current version for tests
- SettingsForTests.ConfigurationStatus = UmbracoVersion.Current.ToString(3);
- }
}
///
@@ -136,8 +161,8 @@ namespace Umbraco.Tests.TestHelpers
{
get
{
- var att = this.GetType().GetCustomAttribute(false);
- return att != null ? att.Behavior : DatabaseBehavior.NoDatabasePerFixture;
+ var att = GetType().GetCustomAttribute(false);
+ return att?.Behavior ?? DatabaseBehavior.NoDatabasePerFixture;
}
}
@@ -238,7 +263,7 @@ namespace Umbraco.Tests.TestHelpers
///
/// Creates the tables and data for the database
///
- protected virtual void InitializeDatabase()
+ protected virtual void InitializeDatabase(ApplicationContext appContext)
{
if (DatabaseTestBehavior == DatabaseBehavior.NoDatabasePerFixture || DatabaseTestBehavior == DatabaseBehavior.EmptyDbFilePerTest)
return;
@@ -254,9 +279,9 @@ namespace Umbraco.Tests.TestHelpers
|| (_isFirstTestInFixture && DatabaseTestBehavior == DatabaseBehavior.NewDbFileAndSchemaPerFixture)))
{
- var schemaHelper = new DatabaseSchemaHelper(DatabaseContext.Database, Logger);
+ var schemaHelper = new DatabaseSchemaHelper(appContext.DatabaseContext.Database, Logger);
//Create the umbraco database and its base data
- schemaHelper.CreateDatabaseSchema(_appContext);
+ schemaHelper.CreateDatabaseSchema(appContext);
//close the connections, we're gonna read this baby in as a byte array so we don't have to re-initialize the
// damn db for each test
@@ -352,15 +377,9 @@ namespace Umbraco.Tests.TestHelpers
}
}
- protected ServiceContext ServiceContext
- {
- get { return ApplicationContext.Services; }
- }
+ protected ServiceContext ServiceContext => ApplicationContext.Services;
- protected DatabaseContext DatabaseContext
- {
- get { return ApplicationContext.DatabaseContext; }
- }
+ protected DatabaseContext DatabaseContext => ApplicationContext.DatabaseContext;
protected UmbracoContext GetUmbracoContext(string url, int templateId, RouteData routeData = null, bool setSingleton = false)
{
diff --git a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs
index f95c0acd70..e0c5ab9c38 100644
--- a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs
+++ b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs
@@ -213,7 +213,7 @@ namespace Umbraco.Tests.TestHelpers
var evtMsgs = new TransientMessagesFactory();
ApplicationContext.Current = new ApplicationContext(
//assign the db context
- new DatabaseContext(new DefaultDatabaseFactory(Core.Configuration.GlobalSettings.UmbracoConnectionName, SqlSyntaxProviders.GetDefaultProviders(Logger), Logger), Logger),
+ new DatabaseContext(new DefaultDatabaseFactory(Core.Configuration.GlobalSettings.UmbracoConnectionName, TestObjects.GetDefaultSqlSyntaxProviders(Logger), Logger), Logger),
//assign the service context
new ServiceContext(
Container.GetInstance(),
@@ -262,15 +262,9 @@ namespace Umbraco.Tests.TestHelpers
Resolution.Freeze();
}
- protected ApplicationContext ApplicationContext
- {
- get { return ApplicationContext.Current; }
- }
+ protected ApplicationContext ApplicationContext => ApplicationContext.Current;
- protected ILogger Logger
- {
- get { return ProfilingLogger.Logger; }
- }
+ protected ILogger Logger => ProfilingLogger.Logger;
protected ProfilingLogger ProfilingLogger { get; private set; }
protected CacheHelper CacheHelper { get; private set; }
@@ -278,9 +272,6 @@ namespace Umbraco.Tests.TestHelpers
// and the number of these will hopefully start getting greatly reduced now that most things are mockable.
internal IServiceContainer Container { get; private set; }
- protected virtual ISqlSyntaxProvider SqlSyntax
- {
- get { return new SqlCeSyntaxProvider(); }
- }
+ protected virtual ISqlSyntaxProvider SqlSyntax => new SqlCeSyntaxProvider();
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/TestHelpers/MockHelper.cs b/src/Umbraco.Tests/TestHelpers/MockHelper.cs
deleted file mode 100644
index f81c7439d7..0000000000
--- a/src/Umbraco.Tests/TestHelpers/MockHelper.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using Moq;
-using Umbraco.Core;
-using Umbraco.Core.Configuration.UmbracoSettings;
-using Umbraco.Core.Logging;
-using Umbraco.Core.Persistence;
-using Umbraco.Core.Persistence.SqlSyntax;
-using Umbraco.Core.Persistence.UnitOfWork;
-using Umbraco.Core.Services;
-
-namespace Umbraco.Tests.TestHelpers
-{
- public static class MockHelper
- {
- public static ServiceContext GetMockedServiceContext()
- {
- return new ServiceContext(
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object,
- new Mock().Object);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs
new file mode 100644
index 0000000000..ceb94bb34d
--- /dev/null
+++ b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Data;
+using System.Data.Common;
+using Moq;
+using Umbraco.Core.Persistence;
+using Umbraco.Core.Services;
+
+namespace Umbraco.Tests.TestHelpers
+{
+ ///
+ /// Provides objects for tests.
+ ///
+ internal static partial class TestObjects
+ {
+ ///
+ /// Gets a mocked IDatabaseFactory.
+ ///
+ /// An IDatabaseFactory.
+ /// A value indicating whether the factory is configured.
+ /// A value indicating whether the factory can connect to the database.
+ /// This is just a void factory that has no actual database.
+ public static IDatabaseFactory GetIDatabaseFactoryMock(bool configured = true, bool canConnect = true)
+ {
+ var databaseFactoryMock = new Mock();
+ databaseFactoryMock.Setup(x => x.Configured).Returns(configured);
+ databaseFactoryMock.Setup(x => x.CanConnect).Returns(canConnect);
+ return databaseFactoryMock.Object;
+ }
+
+ ///
+ /// Gets a mocked service context built with mocked services.
+ ///
+ /// A ServiceContext.
+ public static ServiceContext GetServiceContextMock()
+ {
+ return new ServiceContext(
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object,
+ new Mock().Object);
+ }
+
+ ///
+ /// Gets an opened database connection that can begin a transaction.
+ ///
+ /// A DbConnection.
+ /// This is because NPoco wants a DbConnection, NOT an IDbConnection,
+ /// and DbConnection is hard to mock so we create our own class here.
+ public static DbConnection GetDbConnection()
+ {
+ return new MockDbConnection();
+ }
+
+ #region Inner classes
+
+ private class MockDbConnection : DbConnection
+ {
+ protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
+ {
+ return Mock.Of(); // enough here
+ }
+
+ public override void Close()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void ChangeDatabase(string databaseName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void Open()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override string ConnectionString { get; set; }
+
+ protected override DbCommand CreateDbCommand()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override string Database { get; }
+ public override string DataSource { get; }
+ public override string ServerVersion { get; }
+ public override ConnectionState State => ConnectionState.Open; // else NPoco reopens
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs
new file mode 100644
index 0000000000..4454be3444
--- /dev/null
+++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Common;
+using Moq;
+using NPoco;
+using Umbraco.Core;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Persistence;
+using Umbraco.Core.Persistence.SqlSyntax;
+
+namespace Umbraco.Tests.TestHelpers
+{
+ ///
+ /// Provides objects for tests.
+ ///
+ static partial class TestObjects
+ {
+ ///
+ /// Gets the default ISqlSyntaxProvider objects.
+ ///
+ /// A logger.
+ /// A (lazy) database factory.
+ /// The default ISqlSyntaxProvider objects.
+ public static IEnumerable GetDefaultSqlSyntaxProviders(ILogger logger, Lazy lazyFactory = null)
+ {
+ return new ISqlSyntaxProvider[]
+ {
+ new MySqlSyntaxProvider(logger),
+ new SqlCeSyntaxProvider(),
+ new SqlServerSyntaxProvider(lazyFactory ?? new Lazy(() => null))
+ };
+ }
+
+ ///
+ /// Gets an UmbracoDatabase.
+ ///
+ /// A logger.
+ /// An UmbracoDatabase.
+ /// This is just a void database that has no actual database but pretends to have an open connection
+ /// that can begin a transaction.
+ public static UmbracoDatabase GetUmbracoSqlCeDatabase(ILogger logger)
+ {
+ var syntax = new SqlCeSyntaxProvider();
+ var dbProviderFactory = DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlCe);
+ var connection = TestObjects.GetDbConnection();
+ return new UmbracoDatabase(connection, syntax, DatabaseType.SQLCe, dbProviderFactory, logger);
+ }
+
+ ///
+ /// Gets an UmbracoDatabase.
+ ///
+ /// A logger.
+ /// An UmbracoDatabase.
+ /// This is just a void database that has no actual database but pretends to have an open connection
+ /// that can begin a transaction.
+ public static UmbracoDatabase GetUmbracoSqlServerDatabase(ILogger logger)
+ {
+ var syntax = new SqlServerSyntaxProvider(new Lazy(() => null)); // do NOT try to get the server's version!
+ var dbProviderFactory = DbProviderFactories.GetFactory(Constants.DbProviderNames.SqlServer);
+ var connection = TestObjects.GetDbConnection();
+ return new UmbracoDatabase(connection, syntax, DatabaseType.SqlServer2008, dbProviderFactory, logger);
+ }
+ }
+}
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index 64e1911d32..afb12b3f3f 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -185,6 +185,8 @@
+
+
@@ -436,7 +438,6 @@
-
diff --git a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs
index 357b601e41..667f214a37 100644
--- a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs
+++ b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs
@@ -73,9 +73,11 @@ namespace Umbraco.Tests.Web.Mvc
[Test]
public void Umbraco_Helper_Not_Null()
{
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock();
+
var appCtx = new ApplicationContext(
- new DatabaseContext(new Mock().Object, Mock.Of()),
- MockHelper.GetMockedServiceContext(),
+ new DatabaseContext(databaseFactory, Mock.Of()),
+ TestObjects.GetServiceContextMock(),
CacheHelper.CreateDisabledCacheHelper(),
new ProfilingLogger(Mock.Of(), Mock.Of()));
diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs
index d9b66a2d2a..f853a90c89 100644
--- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs
+++ b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs
@@ -373,7 +373,7 @@ namespace Umbraco.Tests.Web.Mvc
ServiceContext GetServiceContext()
{
- return MockHelper.GetMockedServiceContext();
+ return TestObjects.GetServiceContextMock();
}
ViewContext GetViewContext()
@@ -427,8 +427,10 @@ namespace Umbraco.Tests.Web.Mvc
// ApplicationContext.Current = new ApplicationContext(false) { IsReady = true };
var svcCtx = GetServiceContext();
+ var databaseFactory = TestObjects.GetIDatabaseFactoryMock();
+
var appCtx = new ApplicationContext(
- new DatabaseContext(Mock.Of(), logger),
+ new DatabaseContext(databaseFactory, logger),
svcCtx,
CacheHelper.CreateDisabledCacheHelper(),
new ProfilingLogger(logger, Mock.Of())) { IsReady = true };
diff --git a/src/Umbraco.Web.UI/config/ClientDependency.config b/src/Umbraco.Web.UI/config/ClientDependency.config
index 0023483deb..b086b8a90b 100644
--- a/src/Umbraco.Web.UI/config/ClientDependency.config
+++ b/src/Umbraco.Web.UI/config/ClientDependency.config
@@ -10,7 +10,7 @@ NOTES:
* Compression/Combination/Minification is not enabled unless debug="false" is specified on the 'compiliation' element in the web.config
* A new version will invalidate both client and server cache and create new persisted files
-->
-
+