2020-12-03 13:32:04 +00:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Data.Common;
|
|
|
|
|
using System.Data.SqlClient;
|
|
|
|
|
using System.IO;
|
2020-03-30 20:55:13 +11:00
|
|
|
using Microsoft.AspNetCore.Builder;
|
2020-12-03 13:32:04 +00:00
|
|
|
using Microsoft.Extensions.Configuration;
|
2020-03-30 20:55:13 +11:00
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using Microsoft.Extensions.Hosting;
|
2020-12-03 13:32:04 +00:00
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
using Moq;
|
2020-03-30 20:55:13 +11:00
|
|
|
using NUnit.Framework;
|
2020-12-03 13:32:04 +00:00
|
|
|
using Serilog;
|
|
|
|
|
using Umbraco.Core;
|
2020-03-30 21:53:30 +11:00
|
|
|
using Umbraco.Core.Cache;
|
2020-03-30 20:55:13 +11:00
|
|
|
using Umbraco.Core.Composing;
|
2020-12-03 13:32:04 +00:00
|
|
|
using Umbraco.Core.Configuration.Models;
|
|
|
|
|
using Umbraco.Core.DependencyInjection;
|
2020-03-30 21:53:30 +11:00
|
|
|
using Umbraco.Core.IO;
|
2020-03-30 20:55:13 +11:00
|
|
|
using Umbraco.Core.Persistence;
|
2020-03-30 21:53:30 +11:00
|
|
|
using Umbraco.Core.Persistence.Mappers;
|
2020-12-03 13:32:04 +00:00
|
|
|
using Umbraco.Core.Runtime;
|
2020-03-30 20:55:13 +11:00
|
|
|
using Umbraco.Core.Scoping;
|
2020-03-30 21:53:30 +11:00
|
|
|
using Umbraco.Core.Strings;
|
2020-12-03 13:32:04 +00:00
|
|
|
using Umbraco.Extensions;
|
2020-03-30 21:53:30 +11:00
|
|
|
using Umbraco.Tests.Common.Builders;
|
2020-03-30 20:55:13 +11:00
|
|
|
using Umbraco.Tests.Integration.Extensions;
|
|
|
|
|
using Umbraco.Tests.Integration.Implementations;
|
2020-06-30 20:11:39 +02:00
|
|
|
using Umbraco.Tests.Testing;
|
2020-06-09 07:49:26 +02:00
|
|
|
using Umbraco.Web;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
|
|
|
|
namespace Umbraco.Tests.Integration.Testing
|
|
|
|
|
{
|
2020-09-02 18:10:29 +10:00
|
|
|
|
2020-03-30 20:55:13 +11:00
|
|
|
/// <summary>
|
|
|
|
|
/// Abstract class for integration tests
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// This will use a Host Builder to boot and install Umbraco ready for use
|
|
|
|
|
/// </remarks>
|
|
|
|
|
[SingleThreaded]
|
|
|
|
|
[NonParallelizable]
|
|
|
|
|
public abstract class UmbracoIntegrationTest
|
|
|
|
|
{
|
2020-09-04 00:27:43 +10:00
|
|
|
private List<Action> _testTeardown = null;
|
|
|
|
|
private List<Action> _fixtureTeardown = new List<Action>();
|
2020-09-02 18:10:29 +10:00
|
|
|
|
2020-09-04 00:27:43 +10:00
|
|
|
public void OnTestTearDown(Action tearDown)
|
|
|
|
|
{
|
|
|
|
|
if (_testTeardown == null)
|
|
|
|
|
_testTeardown = new List<Action>();
|
|
|
|
|
_testTeardown.Add(tearDown);
|
|
|
|
|
}
|
2020-09-02 18:10:29 +10:00
|
|
|
|
2020-09-04 00:27:43 +10:00
|
|
|
public void OnFixtureTearDown(Action tearDown) => _fixtureTeardown.Add(tearDown);
|
2020-09-02 18:10:29 +10:00
|
|
|
|
|
|
|
|
[OneTimeTearDown]
|
2020-09-04 00:27:43 +10:00
|
|
|
public void FixtureTearDown()
|
|
|
|
|
{
|
2020-12-03 13:32:04 +00:00
|
|
|
foreach (var a in _fixtureTeardown)
|
|
|
|
|
a();
|
2020-09-04 00:27:43 +10:00
|
|
|
}
|
2020-09-02 18:10:29 +10:00
|
|
|
|
|
|
|
|
[TearDown]
|
2020-09-04 00:27:43 +10:00
|
|
|
public virtual void TearDown()
|
|
|
|
|
{
|
2020-11-10 08:50:47 +00:00
|
|
|
if (_testTeardown != null)
|
|
|
|
|
{
|
2020-12-03 13:32:04 +00:00
|
|
|
foreach (var a in _testTeardown)
|
|
|
|
|
a();
|
2020-11-10 08:50:47 +00:00
|
|
|
}
|
2020-09-04 00:27:43 +10:00
|
|
|
_testTeardown = null;
|
2020-10-05 13:33:39 +02:00
|
|
|
FirstTestInFixture = false;
|
|
|
|
|
FirstTestInSession = false;
|
2020-09-04 00:27:43 +10:00
|
|
|
}
|
2020-09-02 18:10:29 +10:00
|
|
|
|
2020-10-27 14:10:19 +01:00
|
|
|
[TearDown]
|
|
|
|
|
public virtual void TearDown_Logging()
|
|
|
|
|
{
|
2020-10-16 10:45:22 +02:00
|
|
|
TestContext.Progress.Write($" {TestContext.CurrentContext.Result.Outcome.Status}");
|
2020-09-04 00:27:43 +10:00
|
|
|
}
|
2020-09-02 18:10:29 +10:00
|
|
|
|
2020-10-27 14:10:19 +01:00
|
|
|
[SetUp]
|
|
|
|
|
public virtual void SetUp_Logging()
|
|
|
|
|
{
|
|
|
|
|
TestContext.Progress.Write($"Start test {TestCount++}: {TestContext.CurrentContext.Test.Name}");
|
|
|
|
|
}
|
2020-11-10 08:50:47 +00:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
[SetUp]
|
2020-10-05 10:02:11 +02:00
|
|
|
public virtual void Setup()
|
2020-09-02 18:10:29 +10:00
|
|
|
{
|
2020-10-28 14:54:16 +01:00
|
|
|
InMemoryConfiguration[Constants.Configuration.ConfigGlobal + ":" + nameof(GlobalSettings.InstallEmptyDatabase)] = "true";
|
2020-09-02 18:10:29 +10:00
|
|
|
var hostBuilder = CreateHostBuilder();
|
2020-10-16 08:38:25 +02:00
|
|
|
|
2020-10-16 09:52:39 +02:00
|
|
|
var host = hostBuilder.Start();
|
2020-10-16 10:45:22 +02:00
|
|
|
|
2020-09-17 10:35:11 +02:00
|
|
|
Services = host.Services;
|
2020-09-02 18:10:29 +10:00
|
|
|
var app = new ApplicationBuilder(host.Services);
|
2020-10-16 07:08:50 +02:00
|
|
|
|
2020-10-16 10:45:22 +02:00
|
|
|
Configure(app);
|
2020-10-16 07:08:50 +02:00
|
|
|
|
2020-09-11 21:13:18 +02:00
|
|
|
OnFixtureTearDown(() => host.Dispose());
|
2020-09-02 18:10:29 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region Generic Host Builder and Runtime
|
|
|
|
|
|
2020-10-06 18:43:07 +02:00
|
|
|
private ILoggerFactory CreateLoggerFactory()
|
|
|
|
|
{
|
2020-11-19 20:05:28 +00:00
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var testOptions = TestOptionAttributeBase.GetTestOptions<UmbracoTestAttribute>();
|
|
|
|
|
switch (testOptions.Logger)
|
|
|
|
|
{
|
|
|
|
|
case UmbracoTestOptions.Logger.Mock:
|
|
|
|
|
return NullLoggerFactory.Instance;
|
|
|
|
|
case UmbracoTestOptions.Logger.Serilog:
|
|
|
|
|
return Microsoft.Extensions.Logging.LoggerFactory.Create(builder => { builder.AddSerilog(); });
|
|
|
|
|
case UmbracoTestOptions.Logger.Console:
|
|
|
|
|
return Microsoft.Extensions.Logging.LoggerFactory.Create(builder => { builder.AddConsole(); });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch
|
2020-10-06 18:43:07 +02:00
|
|
|
{
|
2020-11-19 20:05:28 +00:00
|
|
|
// ignored
|
2020-10-06 18:43:07 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-19 20:05:28 +00:00
|
|
|
return NullLoggerFactory.Instance;
|
2020-10-06 18:43:07 +02:00
|
|
|
}
|
2020-11-19 20:05:28 +00:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
/// <summary>
|
|
|
|
|
/// Create the Generic Host and execute startup ConfigureServices/Configure calls
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public virtual IHostBuilder CreateHostBuilder()
|
|
|
|
|
{
|
|
|
|
|
var hostBuilder = Host.CreateDefaultBuilder()
|
|
|
|
|
// IMPORTANT: We Cannot use UseStartup, there's all sorts of threads about this with testing. Although this can work
|
|
|
|
|
// if you want to setup your tests this way, it is a bit annoying to do that as the WebApplicationFactory will
|
|
|
|
|
// create separate Host instances. So instead of UseStartup, we just call ConfigureServices/Configure ourselves,
|
|
|
|
|
// and in the case of the UmbracoTestServerTestBase it will use the ConfigureWebHost to Configure the IApplicationBuilder directly.
|
|
|
|
|
//.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(GetType()); })
|
2020-10-26 10:47:14 +00:00
|
|
|
.UseUmbraco()
|
2020-09-02 18:10:29 +10:00
|
|
|
.ConfigureAppConfiguration((context, configBuilder) =>
|
|
|
|
|
{
|
|
|
|
|
context.HostingEnvironment = TestHelper.GetWebHostEnvironment();
|
2020-10-28 14:54:16 +01:00
|
|
|
configBuilder.Sources.Clear();
|
2020-09-02 18:10:29 +10:00
|
|
|
configBuilder.AddInMemoryCollection(InMemoryConfiguration);
|
2020-10-28 14:54:16 +01:00
|
|
|
|
|
|
|
|
Configuration = configBuilder.Build();
|
2020-09-02 18:10:29 +10:00
|
|
|
})
|
|
|
|
|
.ConfigureServices((hostContext, services) =>
|
|
|
|
|
{
|
2020-10-06 18:43:07 +02:00
|
|
|
services.AddTransient(_ => CreateLoggerFactory());
|
2020-09-02 18:10:29 +10:00
|
|
|
ConfigureServices(services);
|
|
|
|
|
});
|
|
|
|
|
return hostBuilder;
|
|
|
|
|
}
|
2020-12-03 13:32:04 +00:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region IStartup
|
|
|
|
|
|
|
|
|
|
public virtual void ConfigureServices(IServiceCollection services)
|
|
|
|
|
{
|
|
|
|
|
services.AddSingleton(TestHelper.DbProviderFactoryCreator);
|
|
|
|
|
var webHostEnvironment = TestHelper.GetWebHostEnvironment();
|
|
|
|
|
services.AddRequiredNetCoreServices(TestHelper, webHostEnvironment);
|
|
|
|
|
|
|
|
|
|
// Add it!
|
2020-11-19 09:06:04 +00:00
|
|
|
|
2020-11-24 09:22:38 +00:00
|
|
|
var typeLoader = services.AddTypeLoader(
|
|
|
|
|
GetType().Assembly,
|
|
|
|
|
webHostEnvironment,
|
|
|
|
|
TestHelper.GetHostingEnvironment(),
|
|
|
|
|
TestHelper.ConsoleLoggerFactory,
|
|
|
|
|
AppCaches.NoCache,
|
|
|
|
|
Configuration,
|
|
|
|
|
TestHelper.Profiler);
|
2020-11-20 11:48:32 +00:00
|
|
|
var builder = new UmbracoBuilder(services, Configuration, typeLoader, TestHelper.ConsoleLoggerFactory);
|
|
|
|
|
|
2020-11-20 12:24:16 +00:00
|
|
|
|
2020-11-23 10:27:13 +00:00
|
|
|
builder.Services.AddLogger(TestHelper.GetHostingEnvironment(), TestHelper.GetLoggingConfiguration(), Configuration);
|
2020-11-20 12:24:16 +00:00
|
|
|
|
2020-11-19 09:06:04 +00:00
|
|
|
builder.AddConfiguration()
|
2020-11-20 12:24:16 +00:00
|
|
|
.AddUmbracoCore();
|
2020-09-04 00:27:43 +10:00
|
|
|
|
2020-11-20 11:48:32 +00:00
|
|
|
builder.Services.AddUnique<AppCaches>(GetAppCaches());
|
2020-11-20 11:11:52 +00:00
|
|
|
builder.Services.AddUnique<IUmbracoBootPermissionChecker>(Mock.Of<IUmbracoBootPermissionChecker>());
|
|
|
|
|
builder.Services.AddUnique<IMainDom>(TestHelper.MainDom);
|
|
|
|
|
|
2020-09-30 14:27:18 +02:00
|
|
|
services.AddSignalR();
|
|
|
|
|
|
2020-11-19 09:06:04 +00:00
|
|
|
builder.AddWebComponents();
|
|
|
|
|
builder.AddRuntimeMinifier();
|
|
|
|
|
builder.AddBackOffice();
|
2020-11-25 11:55:16 +11:00
|
|
|
builder.AddBackOfficeIdentity();
|
2020-09-02 18:10:29 +10:00
|
|
|
|
|
|
|
|
services.AddMvc();
|
|
|
|
|
|
2020-11-19 09:06:04 +00:00
|
|
|
builder.Build();
|
|
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
CustomTestSetup(services);
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-29 14:08:01 +01:00
|
|
|
protected virtual AppCaches GetAppCaches()
|
|
|
|
|
{
|
|
|
|
|
// Disable caches for integration tests
|
|
|
|
|
return AppCaches.NoCache;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
public virtual void Configure(IApplicationBuilder app)
|
|
|
|
|
{
|
2020-11-19 20:05:28 +00:00
|
|
|
UseTestLocalDb(app.ApplicationServices);
|
|
|
|
|
|
2020-10-16 07:08:50 +02:00
|
|
|
//get the currently set options
|
2020-09-02 18:10:29 +10:00
|
|
|
var testOptions = TestOptionAttributeBase.GetTestOptions<UmbracoTestAttribute>();
|
|
|
|
|
if (testOptions.Boot)
|
|
|
|
|
{
|
2020-10-22 21:16:44 +11:00
|
|
|
Services.GetRequiredService<IBackOfficeSecurityFactory>().EnsureBackOfficeSecurity();
|
2020-10-16 07:08:50 +02:00
|
|
|
Services.GetRequiredService<IUmbracoContextFactory>().EnsureUmbracoContext();
|
|
|
|
|
app.UseUmbracoCore(); // Takes 200 ms
|
2020-11-10 08:50:47 +00:00
|
|
|
|
|
|
|
|
OnTestTearDown(TerminateCoreRuntime);
|
2020-09-02 18:10:29 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-10 08:50:47 +00:00
|
|
|
/// <remarks>
|
|
|
|
|
/// Some IComponents hook onto static events (e.g. Published in ContentService)
|
|
|
|
|
/// If these fire after the components host has been shutdown, errors can occur.
|
|
|
|
|
/// If CoreRuntime.Start() is called We also need to de-register the events.
|
|
|
|
|
/// </remarks>
|
|
|
|
|
protected void TerminateCoreRuntime()
|
|
|
|
|
{
|
|
|
|
|
Services.GetRequiredService<IRuntime>().Terminate();
|
2020-11-19 20:47:41 +00:00
|
|
|
StaticApplicationLogging.Initialize(null);
|
2020-11-10 08:50:47 +00:00
|
|
|
}
|
|
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region LocalDb
|
|
|
|
|
|
|
|
|
|
private static readonly object _dbLocker = new object();
|
2020-11-27 19:15:49 +00:00
|
|
|
private static ITestDatabase _dbInstance;
|
2020-09-02 18:10:29 +10:00
|
|
|
|
2020-11-19 20:05:28 +00:00
|
|
|
protected void UseTestLocalDb(IServiceProvider serviceProvider)
|
2020-09-02 18:10:29 +10:00
|
|
|
{
|
2020-11-19 20:47:41 +00:00
|
|
|
var state = serviceProvider.GetRequiredService<IRuntimeState>();
|
2020-11-19 20:05:28 +00:00
|
|
|
var databaseFactory = serviceProvider.GetRequiredService<IUmbracoDatabaseFactory>();
|
|
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
// This will create a db, install the schema and ensure the app is configured to run
|
2020-11-30 12:14:53 +00:00
|
|
|
InstallTestLocalDb(databaseFactory, serviceProvider.GetRequiredService<ILoggerFactory>(), state, TestHelper.WorkingDirectory);
|
2020-11-19 20:05:28 +00:00
|
|
|
TestDBConnectionString = databaseFactory.ConnectionString;
|
2020-09-02 18:10:29 +10:00
|
|
|
InMemoryConfiguration["ConnectionStrings:" + Constants.System.UmbracoConnectionName] = TestDBConnectionString;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-30 20:55:13 +11:00
|
|
|
/// <summary>
|
|
|
|
|
/// Get or create an instance of <see cref="LocalDbTestDatabase"/>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="filesPath"></param>
|
|
|
|
|
/// <param name="logger"></param>
|
2020-09-17 12:52:25 +02:00
|
|
|
/// <param name="loggerFactory"></param>
|
2020-03-30 20:55:13 +11:00
|
|
|
/// <param name="globalSettings"></param>
|
|
|
|
|
/// <param name="dbFactory"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// There must only be ONE instance shared between all tests in a session
|
|
|
|
|
/// </remarks>
|
2020-11-27 19:15:49 +00:00
|
|
|
private static ITestDatabase GetOrCreateDatabase(string filesPath, ILoggerFactory loggerFactory, IUmbracoDatabaseFactory dbFactory)
|
2020-03-30 20:55:13 +11:00
|
|
|
{
|
|
|
|
|
lock (_dbLocker)
|
|
|
|
|
{
|
2020-12-03 13:32:04 +00:00
|
|
|
if (_dbInstance != null)
|
|
|
|
|
return _dbInstance;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
2020-11-27 19:15:49 +00:00
|
|
|
_dbInstance = TestDatabaseFactory.Create(filesPath, loggerFactory, dbFactory);
|
2020-03-30 20:55:13 +11:00
|
|
|
return _dbInstance;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a LocalDb instance to use for the test
|
|
|
|
|
/// </summary>
|
2020-09-17 12:52:25 +02:00
|
|
|
/// <param name="runtimeState"></param>
|
2020-09-02 18:10:29 +10:00
|
|
|
/// <param name="workingDirectory"></param>
|
|
|
|
|
/// <param name="connectionString"></param>
|
2020-09-17 12:52:25 +02:00
|
|
|
/// <param name="databaseFactory"></param>
|
|
|
|
|
/// <param name="loggerFactory"></param>
|
|
|
|
|
/// <param name="globalSettings"></param>
|
2020-09-02 18:10:29 +10:00
|
|
|
/// <returns></returns>
|
|
|
|
|
private void InstallTestLocalDb(
|
2020-09-18 12:53:06 +02:00
|
|
|
IUmbracoDatabaseFactory databaseFactory, ILoggerFactory loggerFactory,
|
2020-11-10 08:50:47 +00:00
|
|
|
IRuntimeState runtimeState, string workingDirectory)
|
2020-09-02 18:10:29 +10:00
|
|
|
{
|
|
|
|
|
var dbFilePath = Path.Combine(workingDirectory, "LocalDb");
|
2020-03-30 20:55:13 +11:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
// get the currently set db options
|
|
|
|
|
var testOptions = TestOptionAttributeBase.GetTestOptions<UmbracoTestAttribute>();
|
2020-03-30 20:55:13 +11:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
if (testOptions.Database == UmbracoTestOptions.Database.None)
|
|
|
|
|
return;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
// need to manually register this factory
|
|
|
|
|
DbProviderFactories.RegisterFactory(Constants.DbProviderNames.SqlServer, SqlClientFactory.Instance);
|
2020-03-30 20:55:13 +11:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
if (!Directory.Exists(dbFilePath))
|
|
|
|
|
Directory.CreateDirectory(dbFilePath);
|
2020-03-30 20:55:13 +11:00
|
|
|
|
2020-09-18 12:53:06 +02:00
|
|
|
var db = GetOrCreateDatabase(dbFilePath, loggerFactory, databaseFactory);
|
2020-03-30 20:55:13 +11:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
switch (testOptions.Database)
|
|
|
|
|
{
|
|
|
|
|
case UmbracoTestOptions.Database.NewSchemaPerTest:
|
2020-03-30 20:55:13 +11:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
// New DB + Schema
|
|
|
|
|
var newSchemaDbId = db.AttachSchema();
|
2020-03-30 20:55:13 +11:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
// Add teardown callback
|
|
|
|
|
OnTestTearDown(() => db.Detach(newSchemaDbId));
|
2020-06-09 07:49:26 +02:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
// We must re-configure our current factory since attaching a new LocalDb from the pool changes connection strings
|
|
|
|
|
if (!databaseFactory.Configured)
|
|
|
|
|
{
|
|
|
|
|
databaseFactory.Configure(db.ConnectionString, Constants.DatabaseProviders.SqlServer);
|
|
|
|
|
}
|
2020-05-17 10:39:30 +01:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
// re-run the runtime level check
|
|
|
|
|
runtimeState.DetermineRuntimeLevel();
|
2020-06-30 20:11:39 +02:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
Assert.AreEqual(RuntimeLevel.Run, runtimeState.Level);
|
2020-06-30 20:11:39 +02:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
break;
|
|
|
|
|
case UmbracoTestOptions.Database.NewEmptyPerTest:
|
|
|
|
|
var newEmptyDbId = db.AttachEmpty();
|
2020-03-30 20:55:13 +11:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
// Add teardown callback
|
|
|
|
|
OnTestTearDown(() => db.Detach(newEmptyDbId));
|
2020-03-30 20:55:13 +11:00
|
|
|
|
2020-10-28 14:54:16 +01:00
|
|
|
// We must re-configure our current factory since attaching a new LocalDb from the pool changes connection strings
|
|
|
|
|
if (!databaseFactory.Configured)
|
|
|
|
|
{
|
|
|
|
|
databaseFactory.Configure(db.ConnectionString, Constants.DatabaseProviders.SqlServer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// re-run the runtime level check
|
|
|
|
|
runtimeState.DetermineRuntimeLevel();
|
|
|
|
|
|
|
|
|
|
Assert.AreEqual(RuntimeLevel.Install, runtimeState.Level);
|
2020-06-09 07:49:26 +02:00
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
break;
|
|
|
|
|
case UmbracoTestOptions.Database.NewSchemaPerFixture:
|
2020-10-06 14:16:29 +02:00
|
|
|
// Only attach schema once per fixture
|
|
|
|
|
// Doing it more than once will block the process since the old db hasn't been detached
|
|
|
|
|
// and it would be the same as NewSchemaPerTest even if it didn't block
|
2020-10-05 13:33:39 +02:00
|
|
|
if (FirstTestInFixture)
|
2020-10-02 14:16:36 +02:00
|
|
|
{
|
2020-10-02 14:35:24 +02:00
|
|
|
// New DB + Schema
|
|
|
|
|
var newSchemaFixtureDbId = db.AttachSchema();
|
2020-09-02 18:10:29 +10:00
|
|
|
|
2020-10-02 14:35:24 +02:00
|
|
|
// Add teardown callback
|
2020-10-06 14:16:29 +02:00
|
|
|
OnFixtureTearDown(() => db.Detach(newSchemaFixtureDbId));
|
2020-10-02 14:16:36 +02:00
|
|
|
}
|
2020-09-02 18:10:29 +10:00
|
|
|
|
2020-10-02 14:35:24 +02:00
|
|
|
// We must re-configure our current factory since attaching a new LocalDb from the pool changes connection strings
|
|
|
|
|
if (!databaseFactory.Configured)
|
|
|
|
|
{
|
|
|
|
|
databaseFactory.Configure(db.ConnectionString, Constants.DatabaseProviders.SqlServer);
|
|
|
|
|
}
|
2020-09-02 18:10:29 +10:00
|
|
|
|
2020-10-02 14:35:24 +02:00
|
|
|
// re-run the runtime level check
|
|
|
|
|
runtimeState.DetermineRuntimeLevel();
|
2020-09-02 18:10:29 +10:00
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case UmbracoTestOptions.Database.NewEmptyPerFixture:
|
2020-10-28 14:54:16 +01:00
|
|
|
// Only attach schema once per fixture
|
|
|
|
|
// Doing it more than once will block the process since the old db hasn't been detached
|
|
|
|
|
// and it would be the same as NewSchemaPerTest even if it didn't block
|
|
|
|
|
if (FirstTestInFixture)
|
|
|
|
|
{
|
|
|
|
|
// New DB + Schema
|
|
|
|
|
var newEmptyFixtureDbId = db.AttachEmpty();
|
2020-09-02 18:10:29 +10:00
|
|
|
|
2020-10-28 14:54:16 +01:00
|
|
|
// Add teardown callback
|
|
|
|
|
OnFixtureTearDown(() => db.Detach(newEmptyFixtureDbId));
|
|
|
|
|
}
|
2020-09-02 18:10:29 +10:00
|
|
|
|
2020-10-28 14:54:16 +01:00
|
|
|
// We must re-configure our current factory since attaching a new LocalDb from the pool changes connection strings
|
|
|
|
|
if (!databaseFactory.Configured)
|
|
|
|
|
{
|
|
|
|
|
databaseFactory.Configure(db.ConnectionString, Constants.DatabaseProviders.SqlServer);
|
|
|
|
|
}
|
2020-09-02 18:10:29 +10:00
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
throw new ArgumentOutOfRangeException(nameof(testOptions), testOptions, null);
|
|
|
|
|
}
|
2020-03-30 20:55:13 +11:00
|
|
|
}
|
|
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
#endregion
|
2020-07-01 17:42:39 +02:00
|
|
|
|
2020-03-30 21:53:30 +11:00
|
|
|
#region Common services
|
|
|
|
|
|
2020-09-02 18:10:29 +10:00
|
|
|
protected virtual T GetRequiredService<T>() => Services.GetRequiredService<T>();
|
|
|
|
|
|
|
|
|
|
public Dictionary<string, string> InMemoryConfiguration { get; } = new Dictionary<string, string>();
|
|
|
|
|
|
|
|
|
|
public IConfiguration Configuration { get; protected set; }
|
|
|
|
|
|
|
|
|
|
public TestHelper TestHelper = new TestHelper();
|
|
|
|
|
|
2020-10-21 13:54:22 +02:00
|
|
|
protected virtual string TestDBConnectionString { get; private set; }
|
2020-06-17 16:39:28 +02:00
|
|
|
|
2020-05-17 10:39:30 +01:00
|
|
|
protected virtual Action<IServiceCollection> CustomTestSetup => services => { };
|
|
|
|
|
|
2020-03-30 20:55:13 +11:00
|
|
|
/// <summary>
|
|
|
|
|
/// Returns the DI container
|
|
|
|
|
/// </summary>
|
2020-09-02 18:10:29 +10:00
|
|
|
protected IServiceProvider Services { get; set; }
|
2020-03-30 20:55:13 +11:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Returns the <see cref="IScopeProvider"/>
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected IScopeProvider ScopeProvider => Services.GetRequiredService<IScopeProvider>();
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Returns the <see cref="IScopeAccessor"/>
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected IScopeAccessor ScopeAccessor => Services.GetRequiredService<IScopeAccessor>();
|
|
|
|
|
|
2020-09-17 10:35:11 +02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Returns the <see cref="ILoggerFactory"/>
|
|
|
|
|
/// </summary>
|
2020-10-06 18:43:07 +02:00
|
|
|
protected ILoggerFactory LoggerFactory => Services.GetRequiredService<ILoggerFactory>();
|
2020-09-17 10:35:11 +02:00
|
|
|
|
2020-03-30 21:53:30 +11:00
|
|
|
protected AppCaches AppCaches => Services.GetRequiredService<AppCaches>();
|
|
|
|
|
protected IIOHelper IOHelper => Services.GetRequiredService<IIOHelper>();
|
|
|
|
|
protected IShortStringHelper ShortStringHelper => Services.GetRequiredService<IShortStringHelper>();
|
2020-08-24 12:34:37 +02:00
|
|
|
protected GlobalSettings GlobalSettings => Services.GetRequiredService<IOptions<GlobalSettings>>().Value;
|
2020-03-30 21:53:30 +11:00
|
|
|
protected IMapperCollection Mappers => Services.GetRequiredService<IMapperCollection>();
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Builders
|
|
|
|
|
|
2020-10-07 11:23:31 +02:00
|
|
|
protected UserBuilder UserBuilderInstance = new UserBuilder();
|
|
|
|
|
protected UserGroupBuilder UserGroupBuilderInstance = new UserGroupBuilder();
|
2020-03-30 21:53:30 +11:00
|
|
|
|
|
|
|
|
#endregion
|
2020-10-05 13:33:39 +02:00
|
|
|
|
|
|
|
|
protected static bool FirstTestInSession = true;
|
|
|
|
|
|
|
|
|
|
protected bool FirstTestInFixture = true;
|
2020-10-27 14:10:19 +01:00
|
|
|
protected static int TestCount = 1;
|
2020-03-30 20:55:13 +11:00
|
|
|
}
|
|
|
|
|
}
|