2020-03-30 20:55:13 +11:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using Microsoft.AspNetCore.Builder;
|
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
|
using Microsoft.Extensions.Hosting;
|
2020-06-30 20:11:39 +02:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
using NUnit.Framework;
|
2020-03-30 21:53:30 +11:00
|
|
|
|
using Umbraco.Core.Cache;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
using Umbraco.Core.Composing;
|
|
|
|
|
|
using Umbraco.Core.Composing.LightInject;
|
|
|
|
|
|
using Umbraco.Core.Configuration;
|
2020-03-30 21:53:30 +11:00
|
|
|
|
using Umbraco.Core.IO;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
using Umbraco.Core.Logging;
|
|
|
|
|
|
using Umbraco.Core.Persistence;
|
2020-03-30 21:53:30 +11:00
|
|
|
|
using Umbraco.Core.Persistence.Mappers;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
using Umbraco.Core.Scoping;
|
2020-03-30 21:53:30 +11:00
|
|
|
|
using Umbraco.Core.Strings;
|
|
|
|
|
|
using Umbraco.Tests.Common.Builders;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
using Umbraco.Tests.Integration.Extensions;
|
|
|
|
|
|
using Umbraco.Tests.Integration.Implementations;
|
2020-05-07 10:08:23 +02:00
|
|
|
|
using Umbraco.Extensions;
|
2020-06-30 20:11:39 +02:00
|
|
|
|
using Umbraco.Tests.Testing;
|
2020-06-09 07:49:26 +02:00
|
|
|
|
using Umbraco.Web;
|
2020-06-30 20:11:39 +02:00
|
|
|
|
using ILogger = Umbraco.Core.Logging.ILogger;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Tests.Integration.Testing
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <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
|
|
|
|
|
|
{
|
|
|
|
|
|
public static LightInjectContainer GetUmbracoContainer(out UmbracoServiceProviderFactory serviceProviderFactory)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = UmbracoServiceProviderFactory.CreateServiceContainer();
|
2020-05-12 17:14:39 +10:00
|
|
|
|
serviceProviderFactory = new UmbracoServiceProviderFactory(container, false);
|
2020-03-30 20:55:13 +11:00
|
|
|
|
var umbracoContainer = serviceProviderFactory.GetContainer();
|
|
|
|
|
|
return umbracoContainer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get or create an instance of <see cref="LocalDbTestDatabase"/>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="filesPath"></param>
|
|
|
|
|
|
/// <param name="logger"></param>
|
|
|
|
|
|
/// <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>
|
|
|
|
|
|
public static LocalDbTestDatabase GetOrCreate(string filesPath, ILogger logger, IGlobalSettings globalSettings, IUmbracoDatabaseFactory dbFactory)
|
|
|
|
|
|
{
|
|
|
|
|
|
lock (_dbLocker)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_dbInstance != null) return _dbInstance;
|
|
|
|
|
|
|
|
|
|
|
|
var localDb = new LocalDb();
|
|
|
|
|
|
if (localDb.IsAvailable == false)
|
|
|
|
|
|
throw new InvalidOperationException("LocalDB is not available.");
|
|
|
|
|
|
_dbInstance = new LocalDbTestDatabase(logger, globalSettings, localDb, filesPath, dbFactory);
|
|
|
|
|
|
return _dbInstance;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static readonly object _dbLocker = new object();
|
|
|
|
|
|
private static LocalDbTestDatabase _dbInstance;
|
|
|
|
|
|
|
2020-04-03 13:54:28 +11:00
|
|
|
|
private Action _testTeardown = null;
|
|
|
|
|
|
private Action _fixtureTeardown = null;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
|
|
|
|
|
|
public void OnTestTearDown(Action tearDown)
|
|
|
|
|
|
{
|
2020-04-03 13:54:28 +11:00
|
|
|
|
_testTeardown = tearDown;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void OnFixtureTearDown(Action tearDown)
|
|
|
|
|
|
{
|
2020-04-03 13:54:28 +11:00
|
|
|
|
_fixtureTeardown = tearDown;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[OneTimeTearDown]
|
|
|
|
|
|
public void FixtureTearDown()
|
|
|
|
|
|
{
|
2020-04-03 13:54:28 +11:00
|
|
|
|
_fixtureTeardown?.Invoke();
|
2020-03-30 20:55:13 +11:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[TearDown]
|
|
|
|
|
|
public void TearDown()
|
|
|
|
|
|
{
|
2020-04-03 13:54:28 +11:00
|
|
|
|
_testTeardown?.Invoke();
|
2020-03-30 20:55:13 +11:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[SetUp]
|
|
|
|
|
|
public async Task Setup()
|
|
|
|
|
|
{
|
|
|
|
|
|
var umbracoContainer = GetUmbracoContainer(out var serviceProviderFactory);
|
|
|
|
|
|
var testHelper = new TestHelper();
|
2020-06-30 20:11:39 +02:00
|
|
|
|
// get the currently set db options
|
|
|
|
|
|
var testOptions = TestOptionAttributeBase.GetTestOptions<UmbracoTestAttribute>();
|
2020-03-30 20:55:13 +11:00
|
|
|
|
|
|
|
|
|
|
var hostBuilder = new HostBuilder()
|
|
|
|
|
|
.UseUmbraco(serviceProviderFactory)
|
|
|
|
|
|
.ConfigureServices((hostContext, services) =>
|
|
|
|
|
|
{
|
2020-04-29 08:56:42 +02:00
|
|
|
|
services.AddSingleton(testHelper.DbProviderFactoryCreator);
|
2020-03-30 20:55:13 +11:00
|
|
|
|
var webHostEnvironment = testHelper.GetWebHostEnvironment();
|
|
|
|
|
|
services.AddRequiredNetCoreServices(testHelper, webHostEnvironment);
|
|
|
|
|
|
|
|
|
|
|
|
// Add it!
|
|
|
|
|
|
services.AddUmbracoConfiguration(hostContext.Configuration);
|
2020-04-22 10:29:21 +02:00
|
|
|
|
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, NoAppCache.Instance, testHelper.GetLoggingConfiguration(), out _);
|
2020-06-09 07:49:26 +02:00
|
|
|
|
services.AddUmbracoWebComponents();
|
|
|
|
|
|
services.AddUmbracoRuntimeMinifier(hostContext.Configuration);
|
|
|
|
|
|
services.AddUmbracoBackOffice();
|
|
|
|
|
|
services.AddUmbracoBackOfficeIdentity();
|
|
|
|
|
|
|
|
|
|
|
|
services.AddMvc();
|
2020-05-17 10:39:30 +01:00
|
|
|
|
|
2020-06-30 20:11:39 +02:00
|
|
|
|
|
|
|
|
|
|
services.AddSingleton<ILogger>(new ConsoleLogger(new MessageTemplates()));
|
|
|
|
|
|
|
2020-05-17 10:39:30 +01:00
|
|
|
|
CustomTestSetup(services);
|
2020-03-30 20:55:13 +11:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
var host = await hostBuilder.StartAsync();
|
|
|
|
|
|
var app = new ApplicationBuilder(host.Services);
|
|
|
|
|
|
Services = app.ApplicationServices;
|
|
|
|
|
|
|
2020-06-09 07:49:26 +02:00
|
|
|
|
Services.GetRequiredService<IUmbracoContextFactory>().EnsureUmbracoContext();
|
2020-03-30 20:55:13 +11:00
|
|
|
|
// This will create a db, install the schema and ensure the app is configured to run
|
2020-06-17 16:39:28 +02:00
|
|
|
|
app.UseTestLocalDb(testHelper.WorkingDirectory, this, out var connectionString);
|
|
|
|
|
|
TestDBConnectionString = connectionString;
|
2020-03-30 20:55:13 +11:00
|
|
|
|
|
2020-06-30 20:11:39 +02:00
|
|
|
|
if (testOptions.Boot)
|
|
|
|
|
|
{
|
|
|
|
|
|
app.UseUmbracoCore();
|
|
|
|
|
|
}
|
2020-06-09 07:49:26 +02:00
|
|
|
|
|
2020-03-30 20:55:13 +11:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-01 17:42:39 +02:00
|
|
|
|
protected T GetRequiredService<T>() => Services.GetRequiredService<T>();
|
|
|
|
|
|
|
2020-03-30 21:53:30 +11:00
|
|
|
|
#region Common services
|
|
|
|
|
|
|
2020-06-17 16:39:28 +02:00
|
|
|
|
protected string TestDBConnectionString { get; private set; }
|
|
|
|
|
|
|
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>
|
|
|
|
|
|
protected IServiceProvider Services { get; private set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <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>();
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns the <see cref="ILogger"/>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
protected ILogger Logger => Services.GetRequiredService<ILogger>();
|
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>();
|
|
|
|
|
|
protected IGlobalSettings GlobalSettings => Services.GetRequiredService<IGlobalSettings>();
|
|
|
|
|
|
protected IMapperCollection Mappers => Services.GetRequiredService<IMapperCollection>();
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Builders
|
|
|
|
|
|
|
|
|
|
|
|
protected GlobalSettingsBuilder GlobalSettingsBuilder = new GlobalSettingsBuilder();
|
|
|
|
|
|
protected UserBuilder UserBuilder = new UserBuilder();
|
|
|
|
|
|
protected UserGroupBuilder UserGroupBuilder = new UserGroupBuilder();
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
2020-03-30 20:55:13 +11:00
|
|
|
|
}
|
|
|
|
|
|
}
|