using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NUnit.Framework;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Composing.LightInject;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Scoping;
using Umbraco.Core.Strings;
using Umbraco.Tests.Common.Builders;
using Umbraco.Tests.Integration.Extensions;
using Umbraco.Tests.Integration.Implementations;
using Umbraco.Web.BackOffice.AspNetCore;
using Umbraco.Extensions;
namespace Umbraco.Tests.Integration.Testing
{
///
/// Abstract class for integration tests
///
///
/// This will use a Host Builder to boot and install Umbraco ready for use
///
[SingleThreaded]
[NonParallelizable]
public abstract class UmbracoIntegrationTest
{
public static LightInjectContainer GetUmbracoContainer(out UmbracoServiceProviderFactory serviceProviderFactory)
{
var container = UmbracoServiceProviderFactory.CreateServiceContainer();
serviceProviderFactory = new UmbracoServiceProviderFactory(container);
var umbracoContainer = serviceProviderFactory.GetContainer();
return umbracoContainer;
}
///
/// Get or create an instance of
///
///
///
///
///
///
///
/// There must only be ONE instance shared between all tests in a session
///
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;
private Action _testTeardown = null;
private Action _fixtureTeardown = null;
public void OnTestTearDown(Action tearDown)
{
_testTeardown = tearDown;
}
public void OnFixtureTearDown(Action tearDown)
{
_fixtureTeardown = tearDown;
}
[OneTimeTearDown]
public void FixtureTearDown()
{
_fixtureTeardown?.Invoke();
}
[TearDown]
public void TearDown()
{
_testTeardown?.Invoke();
}
[SetUp]
public async Task Setup()
{
var umbracoContainer = GetUmbracoContainer(out var serviceProviderFactory);
var testHelper = new TestHelper();
var hostBuilder = new HostBuilder()
.UseUmbraco(serviceProviderFactory)
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton(testHelper.DbProviderFactoryCreator);
var webHostEnvironment = testHelper.GetWebHostEnvironment();
services.AddRequiredNetCoreServices(testHelper, webHostEnvironment);
// Add it!
services.AddUmbracoConfiguration(hostContext.Configuration);
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, NoAppCache.Instance, testHelper.GetLoggingConfiguration(), out _);
});
var host = await hostBuilder.StartAsync();
var app = new ApplicationBuilder(host.Services);
Services = app.ApplicationServices;
// This will create a db, install the schema and ensure the app is configured to run
app.UseTestLocalDb(testHelper.WorkingDirectory, this);
app.UseUmbracoCore();
}
#region Common services
///
/// Returns the DI container
///
protected IServiceProvider Services { get; private set; }
///
/// Returns the
///
protected IScopeProvider ScopeProvider => Services.GetRequiredService();
///
/// Returns the
///
protected IScopeAccessor ScopeAccessor => Services.GetRequiredService();
///
/// Returns the
///
protected ILogger Logger => Services.GetRequiredService();
protected AppCaches AppCaches => Services.GetRequiredService();
protected IIOHelper IOHelper => Services.GetRequiredService();
protected IShortStringHelper ShortStringHelper => Services.GetRequiredService();
protected IGlobalSettings GlobalSettings => Services.GetRequiredService();
protected IMapperCollection Mappers => Services.GetRequiredService();
#endregion
#region Builders
protected GlobalSettingsBuilder GlobalSettingsBuilder = new GlobalSettingsBuilder();
protected UserBuilder UserBuilder = new UserBuilder();
protected UserGroupBuilder UserGroupBuilder = new UserGroupBuilder();
#endregion
}
}