Merge remote-tracking branch 'origin/netcore/dev' into netcore/feature/AB5822-smidge-implementation

# Conflicts:
#	.gitignore
#	src/Umbraco.Core/IO/IIOHelper.cs
This commit is contained in:
Shannon
2020-04-02 22:32:02 +11:00
29 changed files with 187 additions and 194 deletions

1
.gitignore vendored
View File

@@ -170,6 +170,7 @@ build/temp/
/src/Umbraco.Web.UI.NetCore/wwwroot/Media/*
/src/Umbraco.Web.UI.NetCore/wwwroot/is-cache/*
/src/Umbraco.Tests.Integration/App_Data/*
/src/Umbraco.Tests.Integration/TEMP/*
/src/Umbraco.Web.UI.NetCore/wwwroot/Umbraco/assets/*
/src/Umbraco.Web.UI.NetCore/wwwroot/Umbraco/js/*
/src/Umbraco.Web.UI.NetCore/wwwroot/Umbraco/lib/*

View File

@@ -177,7 +177,7 @@ namespace Umbraco.Core.Configuration.Legacy
/// <param name="value">Value of the setting to be saved.</param>
internal static void SaveSetting(string key, string value, IIOHelper ioHelper)
{
var fileName = ioHelper.MapPath(string.Format("{0}/web.config", ioHelper.Root));
var fileName = ioHelper.MapPath("~/web.config");
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single();

View File

@@ -6,6 +6,35 @@ namespace Umbraco.Core
{
public static class AssemblyExtensions
{
private static string _rootDir = "";
/// <summary>
/// Utility method that returns the path to the root of the application, by getting the path to where the assembly where this
/// method is included is present, then traversing until it's past the /bin directory. Ie. this makes it work
/// even if the assembly is in a /bin/debug or /bin/release folder
/// </summary>
/// <returns></returns>
public static string GetRootDirectorySafe(this Assembly executingAssembly)
{
if (string.IsNullOrEmpty(_rootDir) == false)
{
return _rootDir;
}
var codeBase = executingAssembly.CodeBase;
var uri = new Uri(codeBase);
var path = uri.LocalPath;
var baseDirectory = Path.GetDirectoryName(path);
if (string.IsNullOrEmpty(baseDirectory))
throw new Exception("No root directory could be resolved. Please ensure that your Umbraco solution is correctly configured.");
_rootDir = baseDirectory.Contains("bin")
? baseDirectory.Substring(0, baseDirectory.LastIndexOf("bin", StringComparison.OrdinalIgnoreCase) - 1)
: baseDirectory;
return _rootDir;
}
/// <summary>
/// Returns the file used to load the assembly
/// </summary>

View File

@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
public void RemoveConnectionString()
{
var key = Constants.System.UmbracoConnectionName;
var fileName = _ioHelper.MapPath(string.Format("{0}/web.config", _ioHelper.Root));
var fileName = _ioHelper.MapPath("~/web.config");
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single();
@@ -58,7 +58,7 @@ namespace Umbraco.Core.Configuration
var fileSource = "web.config";
var fileName = _ioHelper.MapPath(_ioHelper.Root + "/" + fileSource);
var fileName = _ioHelper.MapPath("~/" + fileSource);
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
if (xml.Root == null) throw new Exception($"Invalid {fileSource} file (no root).");
@@ -71,7 +71,7 @@ namespace Umbraco.Core.Configuration
if (configSourceAttribute != null)
{
fileSource = configSourceAttribute.Value;
fileName = _ioHelper.MapPath(_ioHelper.Root + "/" + fileSource);
fileName = _ioHelper.MapPath("~/" + fileSource);
if (!File.Exists(fileName))
throw new Exception($"Invalid configSource \"{fileSource}\" (no such file).");

View File

@@ -7,8 +7,6 @@ namespace Umbraco.Core.IO
string BackOfficePath { get; }
bool ForceNotHosted { get; set; }
char DirSepChar { get; }
string FindFile(string virtualPath);
string ResolveVirtualUrl(string path);
@@ -43,24 +41,6 @@ namespace Umbraco.Core.IO
bool PathStartsWith(string path, string root, char separator);
/// <summary>
/// Returns the path to the root of the application, by getting the path to where the assembly where this
/// method is included is present, then traversing until it's past the /bin directory. Ie. this makes it work
/// even if the assembly is in a /bin/debug or /bin/release folder
/// </summary>
/// <returns></returns>
string GetRootDirectorySafe();
string GetRootDirectoryBinFolder();
/// <summary>
/// Allows you to overwrite RootDirectory, which would otherwise be resolved
/// automatically upon application start.
/// </summary>
/// <remarks>The supplied path should be the absolute path to the root of the umbraco site.</remarks>
/// <param name="rootPath"></param>
void SetRootDirectory(string rootPath);
void EnsurePathExists(string path);
/// <summary>
@@ -76,6 +56,7 @@ namespace Umbraco.Core.IO
/// <remarks>
/// This is (should be) the same as IHostingEnvironment.ApplicationVirtualPath
/// </remarks>
/// </remarks>
string Root
{
get;

View File

@@ -31,13 +31,6 @@ namespace Umbraco.Core.IO
}
}
/// <summary>
/// Gets or sets a value forcing Umbraco to consider it is non-hosted.
/// </summary>
/// <remarks>This should always be false, unless unit testing.</remarks>
public bool ForceNotHosted { get; set; }
private static string _rootDir = "";
// static compiled regex for faster performance
//private static readonly Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
@@ -113,13 +106,9 @@ namespace Umbraco.Core.IO
: _hostingEnvironment.MapPath("~/" + path.TrimStart('/'));
if (result != null) return result;
}
var root = GetRootDirectorySafe();
var root = Assembly.GetExecutingAssembly().GetRootDirectorySafe();
var newPath = path.TrimStart('~', '/').Replace('/', DirSepChar);
var retval = root + DirSepChar.ToString(CultureInfo.InvariantCulture) + newPath;
@@ -199,71 +188,6 @@ namespace Umbraco.Core.IO
return path[root.Length] == separator;
}
/// <summary>
/// Returns the path to the root of the application, by getting the path to where the assembly where this
/// method is included is present, then traversing until it's past the /bin directory. Ie. this makes it work
/// even if the assembly is in a /bin/debug or /bin/release folder
/// </summary>
/// <returns></returns>
public string GetRootDirectorySafe()
{
if (String.IsNullOrEmpty(_rootDir) == false)
{
return _rootDir;
}
var codeBase = Assembly.GetExecutingAssembly().CodeBase;
var uri = new Uri(codeBase);
var path = uri.LocalPath;
var baseDirectory = Path.GetDirectoryName(path);
if (String.IsNullOrEmpty(baseDirectory))
throw new Exception("No root directory could be resolved. Please ensure that your Umbraco solution is correctly configured.");
_rootDir = baseDirectory.Contains("bin")
? baseDirectory.Substring(0, baseDirectory.LastIndexOf("bin", StringComparison.OrdinalIgnoreCase) - 1)
: baseDirectory;
return _rootDir;
}
public string GetRootDirectoryBinFolder()
{
string binFolder = String.Empty;
if (String.IsNullOrEmpty(_rootDir))
{
binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory.FullName;
return binFolder;
}
binFolder = Path.Combine(GetRootDirectorySafe(), "bin");
// do this all the time (no #if DEBUG) because Umbraco release
// can be used in tests by an app (eg Deploy) being debugged
var debugFolder = Path.Combine(binFolder, "debug");
if (Directory.Exists(debugFolder))
return debugFolder;
var releaseFolder = Path.Combine(binFolder, "release");
if (Directory.Exists(releaseFolder))
return releaseFolder;
if (Directory.Exists(binFolder))
return binFolder;
return _rootDir;
}
/// <summary>
/// Allows you to overwrite RootDirectory, which would otherwise be resolved
/// automatically upon application start.
/// </summary>
/// <remarks>The supplied path should be the absolute path to the root of the umbraco site.</remarks>
/// <param name="rootPath"></param>
public void SetRootDirectory(string rootPath)
{
_rootDir = rootPath;
}
public void EnsurePathExists(string path)
{
var absolutePath = MapPath(path);
@@ -280,7 +204,7 @@ namespace Umbraco.Core.IO
{
if (path.IsFullPath())
{
var rootDirectory = GetRootDirectorySafe();
var rootDirectory = MapPath("~");
var relativePath = path.ToLowerInvariant().Replace(rootDirectory.ToLowerInvariant(), string.Empty);
path = relativePath;
}
@@ -293,6 +217,10 @@ namespace Umbraco.Core.IO
/// <summary>
/// Gets the root path of the application
/// </summary>
/// <remarks>
/// In most cases this will be an empty string which indicates the app is not running in a virtual directory.
/// This is NOT a physical path.
/// </remarks>
public string Root
{
get
@@ -301,7 +229,8 @@ namespace Umbraco.Core.IO
var appPath = _hostingEnvironment.ApplicationVirtualPath;
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (appPath == null || appPath == "/") appPath = string.Empty;
if (appPath == null || appPath == "/")
appPath = string.Empty;
_root = appPath;

View File

@@ -59,7 +59,7 @@ namespace Umbraco.Core.IO
if (Path.IsPathRooted(rootPath) == false)
{
// but the test suite App.config cannot really "root" anything so we have to do it here
var localRoot = _ioHelper.GetRootDirectorySafe();
var localRoot = _ioHelper.MapPath("~");
rootPath = Path.Combine(localRoot, rootPath);
}

View File

@@ -69,11 +69,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions
composition.RegisterUnique<IInstalledPackagesRepository>(factory => CreatePackageRepository(factory, "installedPackages.config"));
composition.RegisterUnique<PackageDataInstallation>();
composition.RegisterUnique<PackageFileInstallation>();
composition.RegisterUnique<IPackageInstallation>(factory => //factory required because we need to pass in a string path
new PackageInstallation(
factory.GetInstance<PackageDataInstallation>(), factory.GetInstance<PackageFileInstallation>(),
factory.GetInstance<CompiledPackageXmlParser>(), factory.GetInstance<IPackageActionRunner>(),
new DirectoryInfo( factory.GetInstance<IIOHelper>().GetRootDirectorySafe())));
composition.RegisterUnique<IPackageInstallation, PackageInstallation>();
return composition;
}

View File

@@ -3,6 +3,7 @@ using System.IO;
using System.Linq;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Migrations.Upgrade;
@@ -24,8 +25,8 @@ namespace Umbraco.Core.Migrations.Install
private readonly IRuntimeState _runtime;
private readonly IMigrationBuilder _migrationBuilder;
private readonly IKeyValueService _keyValueService;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly ILogger _logger;
private readonly IIOHelper _ioHelper;
private readonly IUmbracoVersion _umbracoVersion;
private readonly IDbProviderFactoryCreator _dbProviderFactoryCreator;
private readonly IConfigManipulator _configManipulator;
@@ -43,7 +44,7 @@ namespace Umbraco.Core.Migrations.Install
ILogger logger,
IMigrationBuilder migrationBuilder,
IKeyValueService keyValueService,
IIOHelper ioHelper,
IHostingEnvironment hostingEnvironment,
IUmbracoVersion umbracoVersion,
IDbProviderFactoryCreator dbProviderFactoryCreator,
IConfigManipulator configManipulator)
@@ -55,7 +56,7 @@ namespace Umbraco.Core.Migrations.Install
_logger = logger;
_migrationBuilder = migrationBuilder;
_keyValueService = keyValueService;
_ioHelper = ioHelper;
_hostingEnvironment = hostingEnvironment;
_umbracoVersion = umbracoVersion;
_dbProviderFactoryCreator = dbProviderFactoryCreator;
_configManipulator = configManipulator;
@@ -141,14 +142,14 @@ namespace Umbraco.Core.Migrations.Install
/// </summary>
public void ConfigureEmbeddedDatabaseConnection()
{
ConfigureEmbeddedDatabaseConnection(_databaseFactory, _ioHelper);
ConfigureEmbeddedDatabaseConnection(_databaseFactory);
}
private void ConfigureEmbeddedDatabaseConnection(IUmbracoDatabaseFactory factory, IIOHelper ioHelper)
private void ConfigureEmbeddedDatabaseConnection(IUmbracoDatabaseFactory factory)
{
_configManipulator.SaveConnectionString(EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe);
var path = Path.Combine(ioHelper.GetRootDirectorySafe(), "App_Data", "Umbraco.sdf");
var path = Path.Combine(_hostingEnvironment.ApplicationPhysicalPath, "App_Data", "Umbraco.sdf");
if (File.Exists(path) == false)
{
// this should probably be in a "using (new SqlCeEngine)" clause but not sure

View File

@@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Hosting;
using Umbraco.Core.Models.Packaging;
using Umbraco.Core.Services;
namespace Umbraco.Core.Packaging
{
@@ -27,18 +24,17 @@ namespace Umbraco.Core.Packaging
/// <param name="packageFileInstallation"></param>
/// <param name="parser"></param>
/// <param name="packageActionRunner"></param>
/// <param name="applicationRootFolder">
/// The root folder of the application
/// </param>
/// <param name="hostingEnvironment"></param>
public PackageInstallation(PackageDataInstallation packageDataInstallation, PackageFileInstallation packageFileInstallation, CompiledPackageXmlParser parser, IPackageActionRunner packageActionRunner,
DirectoryInfo applicationRootFolder)
IHostingEnvironment hostingEnvironment)
{
_packageExtraction = new PackageExtraction();
_packageFileInstallation = packageFileInstallation ?? throw new ArgumentNullException(nameof(packageFileInstallation));
_packageDataInstallation = packageDataInstallation ?? throw new ArgumentNullException(nameof(packageDataInstallation));
_parser = parser ?? throw new ArgumentNullException(nameof(parser));
_packageActionRunner = packageActionRunner ?? throw new ArgumentNullException(nameof(packageActionRunner));
_applicationRootFolder = applicationRootFolder ?? throw new ArgumentNullException(nameof(applicationRootFolder));
_applicationRootFolder = new DirectoryInfo(hostingEnvironment.ApplicationPhysicalPath);
}
public CompiledPackage ReadPackage(FileInfo packageFile)

View File

@@ -269,7 +269,7 @@ namespace Umbraco.Core.Runtime
{
var path = GetApplicationRootPath();
if (string.IsNullOrWhiteSpace(path) == false)
IOHelper.SetRootDirectory(path);
IOHelper.Root = path;
}
private bool AcquireMainDom(IMainDom mainDom, IApplicationShutdownRegistry applicationShutdownRegistry)
@@ -363,8 +363,14 @@ namespace Umbraco.Core.Runtime
new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache())));
}
// by default, returns null, meaning that Umbraco should auto-detect the application root path.
// override and return the absolute path to the Umbraco site/solution, if needed
/// <summary>
/// Returns the application path of the site/solution
/// </summary>
/// <returns></returns>
/// <remarks>
/// By default is null which means it's not running in any virtual folder. If the site is running in a virtual folder, this
/// can be overridden and the virtual path returned (i.e. /mysite/)
/// </remarks>
protected virtual string GetApplicationRootPath()
=> null;

View File

@@ -30,6 +30,7 @@ namespace Umbraco.Tests.Common
private readonly ITypeFinder _typeFinder;
private UriUtility _uriUtility;
private IIOHelper _ioHelper;
private string _workingDir;
protected TestHelperBase(Assembly entryAssembly)
{
@@ -61,17 +62,20 @@ namespace Umbraco.Tests.Common
public IConfigsFactory GetConfigsFactory() => new ConfigsFactory();
/// <summary>
/// Gets the current assembly directory.
/// Gets the working directory of the test project.
/// </summary>
/// <value>The assembly directory.</value>
public string CurrentAssemblyDirectory
public virtual string WorkingDirectory
{
get
{
var codeBase = typeof(TestHelperBase).Assembly.CodeBase;
var uri = new Uri(codeBase);
var path = uri.LocalPath;
return Path.GetDirectoryName(path);
if (_workingDir != null) return _workingDir;
var dir = Path.Combine(Assembly.GetExecutingAssembly().GetRootDirectorySafe(), "TEMP");
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
_workingDir = dir;
return _workingDir;
}
}
@@ -108,16 +112,21 @@ namespace Umbraco.Tests.Common
public IWebRoutingSettings WebRoutingSettings => SettingsForTests.GenerateMockWebRoutingSettings();
/// <summary>
/// Maps the given <paramref name="relativePath"/> making it rooted on <see cref="CurrentAssemblyDirectory"/>. <paramref name="relativePath"/> must start with <code>~/</code>
/// Some test files are copied to the /bin (/bin/debug) on build, this is a utility to return their physical path based on a virtual path name
/// </summary>
/// <param name="relativePath">The relative path.</param>
/// <param name="relativePath"></param>
/// <returns></returns>
public string MapPathForTest(string relativePath)
public string MapPathForTestFiles(string relativePath)
{
if (!relativePath.StartsWith("~/"))
throw new ArgumentException("relativePath must start with '~/'", "relativePath");
throw new ArgumentException("relativePath must start with '~/'", nameof(relativePath));
return relativePath.Replace("~/", CurrentAssemblyDirectory + "/");
var codeBase = typeof(TestHelperBase).Assembly.CodeBase;
var uri = new Uri(codeBase);
var path = uri.LocalPath;
var bin = Path.GetDirectoryName(path);
return relativePath.Replace("~/", bin + "/");
}
public IUmbracoVersion GetUmbracoVersion() => new UmbracoVersion(GetConfigs().Global());

View File

@@ -5,6 +5,7 @@ using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NUnit.Framework;
using Umbraco.Configuration.Models;
using Umbraco.Core;
@@ -22,13 +23,16 @@ namespace Umbraco.Tests.Integration.Extensions
/// Creates a LocalDb instance to use for the test
/// </summary>
/// <param name="app"></param>
/// <param name="dbFilePath"></param>
/// <param name="hostEnvironment"></param>
/// <param name="integrationTest"></param>
/// <returns></returns>
public static IApplicationBuilder UseTestLocalDb(this IApplicationBuilder app,
string dbFilePath,
IHostEnvironment hostEnvironment,
UmbracoIntegrationTest integrationTest)
{
var dbFilePath = Path.Combine(hostEnvironment.ContentRootPath, "LocalDb");
// get the currently set db options
var testOptions = TestOptionAttributeBase.GetTestOptions<UmbracoTestAttribute>();

View File

@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Umbraco.Tests.Integration.Implementations;
namespace Umbraco.Tests.Integration.Extensions
@@ -18,6 +19,8 @@ namespace Umbraco.Tests.Integration.Extensions
services.AddSingleton<IHttpContextAccessor>(x => testHelper.GetHttpContextAccessor());
// the generic host does add IHostEnvironment but not this one because we are not actually in a web context
services.AddSingleton<IWebHostEnvironment>(x => webHostEnvironment);
// replace the IHostEnvironment that generic host created too
services.AddSingleton<IHostEnvironment>(x => webHostEnvironment);
}
}
}

View File

@@ -1,9 +1,11 @@

using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Moq;
using System.Data.Common;
using System.IO;
using System.Net;
using Umbraco.Core;
using Umbraco.Core.Cache;
@@ -24,11 +26,12 @@ namespace Umbraco.Tests.Integration.Implementations
public class TestHelper : TestHelperBase
{
private IBackOfficeInfo _backOfficeInfo;
private readonly IHostingEnvironment _hostingEnvironment;
private IHostingEnvironment _hostingEnvironment;
private readonly IApplicationShutdownRegistry _hostingLifetime;
private readonly IIpResolver _ipResolver;
private readonly IWebHostEnvironment _hostEnvironment;
private readonly IHttpContextAccessor _httpContextAccessor;
private string _tempWorkingDir;
public TestHelper() : base(typeof(TestHelper).Assembly)
{
@@ -37,21 +40,44 @@ namespace Umbraco.Tests.Integration.Implementations
_httpContextAccessor = Mock.Of<IHttpContextAccessor>(x => x.HttpContext == httpContext);
_ipResolver = new AspNetIpResolver(_httpContextAccessor);
_hostEnvironment = Mock.Of<IWebHostEnvironment>(x =>
x.ApplicationName == "UmbracoIntegrationTests"
&& x.ContentRootPath == CurrentAssemblyDirectory
&& x.WebRootPath == CurrentAssemblyDirectory); // same folder for now?
_hostingEnvironment = new TestHostingEnvironment(
SettingsForTests.GetDefaultHostingSettings(),
_hostEnvironment,
_httpContextAccessor);
var hostEnvironment = new Mock<IWebHostEnvironment>();
hostEnvironment.Setup(x => x.ApplicationName).Returns("UmbracoIntegrationTests");
hostEnvironment.Setup(x => x.ContentRootPath).Returns(() => WorkingDirectory);
hostEnvironment.Setup(x => x.WebRootPath).Returns(() => WorkingDirectory);
_hostEnvironment = hostEnvironment.Object;
_hostingLifetime = new AspNetCoreApplicationShutdownRegistry(Mock.Of<IHostApplicationLifetime>());
Logger = new ProfilingLogger(new ConsoleLogger(new MessageTemplates()), Profiler);
}
public override string WorkingDirectory
{
get
{
// For Azure Devops we can only store a database in certain locations so we will need to detect if we are running
// on a build server and if so we'll use the %temp% path.
if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("System_DefaultWorkingDirectory")))
{
// we are using Azure Devops!
if (_tempWorkingDir != null) return _tempWorkingDir;
var temp = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoTemp");
Directory.CreateDirectory(temp);
_tempWorkingDir = temp;
return _tempWorkingDir;
}
else
{
return base.WorkingDirectory;
}
}
}
public IUmbracoBootPermissionChecker UmbracoBootPermissionChecker { get; } = new TestUmbracoBootPermissionChecker();
public AppCaches AppCaches { get; } = new AppCaches(NoAppCache.Instance, NoAppCache.Instance, new IsolatedCaches(type => NoAppCache.Instance));
@@ -77,7 +103,12 @@ namespace Umbraco.Tests.Integration.Implementations
return _backOfficeInfo;
}
public override IHostingEnvironment GetHostingEnvironment() => _hostingEnvironment;
public override IHostingEnvironment GetHostingEnvironment()
=> _hostingEnvironment ??= new TestHostingEnvironment(
SettingsForTests.GetDefaultHostingSettings(),
_hostEnvironment,
_httpContextAccessor);
public override IApplicationShutdownRegistry GetHostingEnvironmentLifetime() => _hostingLifetime;
public override IIpResolver GetIpResolver() => _ipResolver;

View File

@@ -8,7 +8,8 @@ namespace Umbraco.Tests.Integration.Implementations
public class TestHostingEnvironment : AspNetCoreHostingEnvironment, Umbraco.Core.Hosting.IHostingEnvironment
{
public TestHostingEnvironment(IHostingSettings hostingSettings, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor) : base(hostingSettings, webHostEnvironment, httpContextAccessor)
public TestHostingEnvironment(IHostingSettings hostingSettings, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor)
: base(hostingSettings, webHostEnvironment, httpContextAccessor)
{
}

View File

@@ -126,7 +126,7 @@ namespace Umbraco.Tests.Integration.Testing
Services = app.ApplicationServices;
// This will create a db, install the schema and ensure the app is configured to run
app.UseTestLocalDb(Path.Combine(testHelper.CurrentAssemblyDirectory, "LocalDb"), this);
app.UseTestLocalDb(Services.GetRequiredService<IHostEnvironment>(), this);
app.UseUmbracoCore();
}

View File

@@ -15,7 +15,7 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings
[SetUp]
public void Init()
{
var config = new FileInfo(TestHelper.MapPathForTest("~/Configurations/UmbracoSettings/web.config"));
var config = new FileInfo(TestHelper.MapPathForTestFiles("~/Configurations/UmbracoSettings/web.config"));
var fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = config.FullName };
var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

View File

@@ -10,14 +10,14 @@ using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Packaging
{
[TestFixture]
class PackageExtractionTests
public class PackageExtractionTests
{
private const string PackageFileName = "Document_Type_Picker_1.1.umb";
private static FileInfo GetTestPackagePath(string packageName)
{
const string testPackagesDirName = "Packaging\\Packages";
string path = Path.Combine(TestHelper.IOHelper.GetRootDirectorySafe(), testPackagesDirName, packageName);
string path = Path.Combine(TestHelper.IOHelper.MapPath("~"), testPackagesDirName, packageName);
return new FileInfo(path);
}

View File

@@ -7,6 +7,7 @@ using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Packaging;
@@ -25,12 +26,15 @@ namespace Umbraco.Tests.Packaging
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)]
public class PackageInstallationTest : TestWithDatabaseBase
{
private Guid _testBaseFolder;
private DirectoryInfo _testBaseFolder;
public override void SetUp()
{
base.SetUp();
_testBaseFolder = Guid.NewGuid();
var path = Path.Combine(TestHelper.WorkingDirectory, Guid.NewGuid().ToString());
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
_testBaseFolder = new DirectoryInfo(path);
}
public override void TearDown()
@@ -38,9 +42,8 @@ namespace Umbraco.Tests.Packaging
base.TearDown();
//clear out files/folders
var path = IOHelper.MapPath("~/" + _testBaseFolder);
if (Directory.Exists(path))
Directory.Delete(path, true);
if (_testBaseFolder.Exists)
_testBaseFolder.Delete(true);
}
private CompiledPackageXmlParser Parser => new CompiledPackageXmlParser(new ConflictingPackageData(ServiceContext.MacroService, ServiceContext.FileService),Factory.GetInstance<IGlobalSettings>());
@@ -60,7 +63,8 @@ namespace Umbraco.Tests.Packaging
PackageDataInstallation,
new PackageFileInstallation(Parser, IOHelper, ProfilingLogger),
Parser, Mock.Of<IPackageActionRunner>(),
applicationRootFolder: new DirectoryInfo(IOHelper.MapPath("~/" + _testBaseFolder))); //we don't want to extract package files to the real root, so extract to a test folder
//we don't want to extract package files to the real root, so extract to a test folder
Mock.Of<IHostingEnvironment>(x => x.ApplicationPhysicalPath == _testBaseFolder.FullName));
private const string DocumentTypePickerPackage = "Document_Type_Picker_1.1.umb";
private const string HelloPackage = "Hello_1.0.0.zip";
@@ -118,10 +122,8 @@ namespace Umbraco.Tests.Packaging
public void Can_Read_Compiled_Package_Warnings()
{
//copy a file to the same path that the package will install so we can detect file conflicts
var path = IOHelper.MapPath("~/" + _testBaseFolder);
Console.WriteLine(path);
var filePath = Path.Combine(path, "bin", "Auros.DocumentTypePicker.dll");
var filePath = Path.Combine(_testBaseFolder.FullName, "bin", "Auros.DocumentTypePicker.dll");
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllText(filePath, "test");
@@ -155,7 +157,7 @@ namespace Umbraco.Tests.Packaging
Assert.AreEqual(1, result.Count);
Assert.AreEqual("bin\\Auros.DocumentTypePicker.dll", result[0]);
Assert.IsTrue(File.Exists(Path.Combine(IOHelper.MapPath("~/" + _testBaseFolder), result[0])));
Assert.IsTrue(File.Exists(Path.Combine(_testBaseFolder.FullName, result[0])));
//make sure the def is updated too
Assert.AreEqual(result.Count, def.Files.Count);

View File

@@ -51,7 +51,7 @@ namespace Umbraco.Tests.Persistence
[Test]
public void CreateDatabase() // FIXME: move to DatabaseBuilderTest!
{
var path = TestHelper.CurrentAssemblyDirectory;
var path = TestHelper.WorkingDirectory;
AppDomain.CurrentDomain.SetData("DataDirectory", path);
// delete database file

View File

@@ -82,10 +82,10 @@ namespace Umbraco.Tests.TestHelpers
public static IConfigsFactory GetConfigsFactory() => _testHelperInternal.GetConfigsFactory();
/// <summary>
/// Gets the current assembly directory.
/// Gets the working directory of the test project.
/// </summary>
/// <value>The assembly directory.</value>
public static string CurrentAssemblyDirectory => _testHelperInternal.CurrentAssemblyDirectory;
public static string WorkingDirectory => _testHelperInternal.WorkingDirectory;
public static IShortStringHelper ShortStringHelper => _testHelperInternal.ShortStringHelper;
public static IJsonSerializer JsonSerializer => _testHelperInternal.JsonSerializer;
@@ -102,12 +102,13 @@ namespace Umbraco.Tests.TestHelpers
public static IWebRoutingSettings WebRoutingSettings => _testHelperInternal.WebRoutingSettings;
/// <summary>
/// Maps the given <paramref name="relativePath"/> making it rooted on <see cref="CurrentAssemblyDirectory"/>. <paramref name="relativePath"/> must start with <code>~/</code>
/// Some test files are copied to the /bin (/bin/debug) on build, this is a utility to return their physical path based on a virtual path name
/// </summary>
/// <param name="relativePath">The relative path.</param>
/// <param name="relativePath"></param>
/// <returns></returns>
public static string MapPathForTest(string relativePath) => _testHelperInternal.MapPathForTest(relativePath);
public static string MapPathForTestFiles(string relativePath) => _testHelperInternal.MapPathForTestFiles(relativePath);
public static void InitializeContentDirectories()
{
@@ -147,7 +148,7 @@ namespace Umbraco.Tests.TestHelpers
public static void CleanUmbracoSettingsConfig()
{
var currDir = new DirectoryInfo(CurrentAssemblyDirectory);
var currDir = new DirectoryInfo(WorkingDirectory);
var umbracoSettingsFile = Path.Combine(currDir.Parent.Parent.FullName, "config", "umbracoSettings.config");
if (File.Exists(umbracoSettingsFile))

View File

@@ -9,6 +9,7 @@ using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Events;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Packaging;
@@ -74,23 +75,21 @@ namespace Umbraco.Tests.TestHelpers
/// <summary>
/// Gets a ServiceContext.
/// </summary>
/// <param name="scopeProvider"></param>
/// <param name="scopeAccessor"></param>
/// <param name="cache">A cache.</param>
/// <param name="logger">A logger.</param>
/// <param name="umbracoVersion">An Umbraco Version.</param>
/// <param name="ioHelper">An io helper.</param>
/// <param name="globalSettings"></param>
/// <param name="umbracoSettings"></param>
/// <param name="contentSettings"></param>
/// <param name="eventMessagesFactory">An event messages factory.</param>
/// <param name="urlSegmentProviders">Some url segment providers.</param>
/// <param name="typeLoader"></param>
/// <param name="umbracoVersion">An Umbraco Version.</param>
/// <param name="factory">A container.</param>
/// <param name="scopeProvider"></param>
/// <returns>A ServiceContext.</returns>
/// <remarks>Should be used sparingly for integration tests only - for unit tests
/// just mock the services to be passed to the ctor of the ServiceContext.</remarks>
public ServiceContext GetServiceContext(
IScopeProvider scopeProvider, IScopeAccessor scopeAccessor,
public ServiceContext GetServiceContext(IScopeProvider scopeProvider, IScopeAccessor scopeAccessor,
AppCaches cache,
ILogger logger,
IIOHelper ioHelper,
@@ -98,7 +97,6 @@ namespace Umbraco.Tests.TestHelpers
IContentSettings contentSettings,
IEventMessagesFactory eventMessagesFactory,
UrlSegmentProviderCollection urlSegmentProviders,
TypeLoader typeLoader,
IUmbracoVersion umbracoVersion,
IFactory factory = null)
{
@@ -187,7 +185,8 @@ namespace Umbraco.Tests.TestHelpers
new PackageDataInstallation(logger, fileService.Value, macroService.Value, localizationService.Value, dataTypeService.Value, entityService.Value, contentTypeService.Value, contentService.Value, propertyEditorCollection, scopeProvider, shortStringHelper, GetGlobalSettings(), localizedTextService.Value),
new PackageFileInstallation(compiledPackageXmlParser, ioHelper, new ProfilingLogger(logger, new TestProfiler())),
compiledPackageXmlParser, Mock.Of<IPackageActionRunner>(),
new DirectoryInfo(ioHelper.GetRootDirectorySafe())), ioHelper);
Mock.Of<IHostingEnvironment>(x => x.ApplicationPhysicalPath == ioHelper.MapPath("~"))),
ioHelper);
});
var relationService = GetLazyService<IRelationService>(factory, c => new RelationService(scopeProvider, logger, eventMessagesFactory, entityService.Value, GetRepo<IRelationRepository>(c), GetRepo<IRelationTypeRepository>(c)));
var tagService = GetLazyService<ITagService>(factory, c => new TagService(scopeProvider, logger, eventMessagesFactory, GetRepo<ITagRepository>(c)));

View File

@@ -62,10 +62,11 @@ namespace Umbraco.Tests.TestHelpers
public override void SetUp()
{
base.SetUp();
var path = TestHelper.CurrentAssemblyDirectory;
// Ensure the data directory is set before continuing
var path = TestHelper.WorkingDirectory;
AppDomain.CurrentDomain.SetData("DataDirectory", path);
base.SetUp();
}
protected override void Compose()
@@ -167,7 +168,7 @@ namespace Umbraco.Tests.TestHelpers
if (Options.Database == UmbracoTestOptions.Database.None)
return;
var path = TestHelper.CurrentAssemblyDirectory;
var path = TestHelper.WorkingDirectory;
//Get the connectionstring settings from config
var settings = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName];
@@ -337,7 +338,7 @@ namespace Umbraco.Tests.TestHelpers
private void RemoveDatabaseFile(Action<Exception> onFail = null)
{
var path = TestHelper.CurrentAssemblyDirectory;
var path = TestHelper.WorkingDirectory;
try
{
var filePath = string.Concat(path, "\\UmbracoNPocoTests.sdf");

View File

@@ -267,7 +267,7 @@ namespace Umbraco.Tests.Testing
profiler = Mock.Of<IProfiler>();
break;
case UmbracoTestOptions.Logger.Serilog:
logger = new SerilogLogger(TestHelper.CoreDebugSettings, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTest("~/unit-test.config")));
logger = new SerilogLogger(TestHelper.CoreDebugSettings, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTestFiles("~/unit-test.config")));
profiler = new LogProfiler(logger);
break;
case UmbracoTestOptions.Logger.Console:

View File

@@ -17,7 +17,8 @@ namespace Umbraco.Tests.UmbracoExamine
[OneTimeSetUp]
public void InitializeFixture()
{
var logger = new SerilogLogger(TestHelper.CoreDebugSettings, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTest("~/unit-test.config")));
var logger = new SerilogLogger(TestHelper.CoreDebugSettings, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTestFiles("~/unit-test.config")));
_profilingLogger = new ProfilingLogger(logger, new LogProfiler(logger));
}

View File

@@ -77,7 +77,7 @@ namespace Umbraco.Tests.Web.Controllers
var baseDir = IOHelper.MapPath("").TrimEnd(IOHelper.DirSepChar);
HttpContext.Current = new HttpContext(new SimpleWorkerRequest("/", baseDir, "", "", new StringWriter()));
}
IOHelper.ForceNotHosted = true;
var usersController = new AuthenticationController(
new TestUserPasswordConfig(),
Factory.GetInstance<IGlobalSettings>(),

View File

@@ -21,8 +21,8 @@ namespace Umbraco.Web.Common.AspNetCore
public AspNetCoreHostingEnvironment(IHostingSettings hostingSettings, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor)
{
_hostingSettings = hostingSettings ?? throw new ArgumentNullException(nameof(hostingSettings));
_webHostEnvironment = webHostEnvironment;
_httpContextAccessor = httpContextAccessor;
_webHostEnvironment = webHostEnvironment ?? throw new ArgumentNullException(nameof(webHostEnvironment));
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
SiteName = webHostEnvironment.ApplicationName;
ApplicationId = AppDomain.CurrentDomain.Id.ToString();

View File

@@ -1,4 +1,5 @@
using System;
using System.Reflection;
using System.Web;
using System.Web.Hosting;
using Umbraco.Core;
@@ -18,7 +19,8 @@ namespace Umbraco.Web.Hosting
_hostingSettings = hostingSettings ?? throw new ArgumentNullException(nameof(hostingSettings));
SiteName = HostingEnvironment.SiteName;
ApplicationId = HostingEnvironment.ApplicationID;
ApplicationPhysicalPath = HostingEnvironment.ApplicationPhysicalPath;
// when we are not hosted (i.e. unit test or otherwise) we'll need to get the root path from the executing assembly
ApplicationPhysicalPath = HostingEnvironment.ApplicationPhysicalPath ?? Assembly.GetExecutingAssembly().GetRootDirectorySafe();
ApplicationVirtualPath = HostingEnvironment.ApplicationVirtualPath;
IISVersion = HttpRuntime.IISVersion;
}