Merge remote-tracking branch 'origin/v10/dev' into v10/feature/nullable-reference-types-in-Umbraco-Core
# Conflicts: # build/build.ps1 # src/Umbraco.Core/Configuration/ConfigConnectionString.cs # src/Umbraco.Core/Configuration/Models/ConnectionStrings.cs # src/Umbraco.Core/Install/InstallSteps/TelemetryIdentifierStep.cs # src/Umbraco.Core/Models/ContentType.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs # tests/Umbraco.Tests.AcceptanceTest/package.json
This commit is contained in:
@@ -39,10 +39,6 @@ namespace Umbraco.Cms.Tests.UnitTests.AutoFixture.Customizations
|
||||
// When requesting an IUserStore ensure we actually uses a IUserLockoutStore
|
||||
fixture.Customize<IUserStore<BackOfficeIdentityUser>>(cc => cc.FromFactory(Mock.Of<IUserLockoutStore<BackOfficeIdentityUser>>));
|
||||
|
||||
fixture.Customize<ConfigConnectionString>(
|
||||
u => u.FromFactory<string, string, string>(
|
||||
(a, b, c) => new ConfigConnectionString(a, b, c)));
|
||||
|
||||
fixture.Customize<IUmbracoVersion>(
|
||||
u => u.FromFactory(
|
||||
() => new UmbracoVersion()));
|
||||
@@ -63,11 +59,6 @@ namespace Umbraco.Cms.Tests.UnitTests.AutoFixture.Customizations
|
||||
Mock.Of<IHostingEnvironment>(x => x.ToAbsolute(It.IsAny<string>()) == "/umbraco" && x.ApplicationVirtualPath == string.Empty),
|
||||
Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run))));
|
||||
|
||||
var configConnectionString = new ConfigConnectionString(
|
||||
"ss",
|
||||
"Data Source=(localdb)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\Umbraco.mdf;Integrated Security=True");
|
||||
fixture.Customize<ConfigConnectionString>(x => x.FromFactory(() => configConnectionString));
|
||||
|
||||
var httpContextAccessor = new HttpContextAccessor { HttpContext = new DefaultHttpContext() };
|
||||
fixture.Customize<HttpContext>(x => x.FromFactory(() => httpContextAccessor.HttpContext));
|
||||
fixture.Customize<IHttpContextAccessor>(x => x.FromFactory(() => httpContextAccessor));
|
||||
|
||||
@@ -14,6 +14,7 @@ using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Mappers;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.SqlSyntax;
|
||||
using Umbraco.Cms.Persistence.SqlServer.Services;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.TestHelpers
|
||||
|
||||
@@ -38,6 +38,7 @@ using Umbraco.Cms.Infrastructure.Mail;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Mappers;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.SqlSyntax;
|
||||
using Umbraco.Cms.Persistence.SqlServer.Services;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Extensions;
|
||||
@@ -61,8 +62,6 @@ namespace Umbraco.Cms.Tests.UnitTests.TestHelpers
|
||||
{
|
||||
}
|
||||
|
||||
public override IDbProviderFactoryCreator DbProviderFactoryCreator { get; } = Mock.Of<IDbProviderFactoryCreator>();
|
||||
|
||||
public override IBulkSqlInsertProvider BulkSqlInsertProvider { get; } = Mock.Of<IBulkSqlInsertProvider>();
|
||||
|
||||
public override IMarchal Marchal { get; } = Mock.Of<IMarchal>();
|
||||
@@ -113,8 +112,6 @@ namespace Umbraco.Cms.Tests.UnitTests.TestHelpers
|
||||
|
||||
public static IVariationContextAccessor VariationContextAccessor => s_testHelperInternal.VariationContextAccessor;
|
||||
|
||||
public static IDbProviderFactoryCreator DbProviderFactoryCreator => s_testHelperInternal.DbProviderFactoryCreator;
|
||||
|
||||
public static IBulkSqlInsertProvider BulkSqlInsertProvider => s_testHelperInternal.BulkSqlInsertProvider;
|
||||
|
||||
public static IMarchal Marchal => s_testHelperInternal.Marchal;
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Tests.UnitTests.AutoFixture;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Configuration;
|
||||
|
||||
[TestFixture]
|
||||
public class ConfigureConnectionStringsTests
|
||||
{
|
||||
private const string UmbracoDbDsn = Constants.System.UmbracoConnectionName;
|
||||
|
||||
private IOptionsSnapshot<ConnectionStrings> GetOptions(IDictionary<string, string> configValues = null)
|
||||
{
|
||||
var configurationBuilder = new ConfigurationBuilder();
|
||||
if (configValues != null)
|
||||
{
|
||||
configurationBuilder.AddInMemoryCollection(configValues);
|
||||
}
|
||||
|
||||
var configuration = configurationBuilder.Build();
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddOptions<ConnectionStrings>().Bind(configuration.GetSection("ConnectionStrings"));
|
||||
services.AddSingleton<IConfigureOptions<ConnectionStrings>, ConfigureConnectionStrings>();
|
||||
services.AddSingleton<IConfiguration>(configuration);
|
||||
|
||||
var container = services.BuildServiceProvider();
|
||||
return container.GetRequiredService<IOptionsSnapshot<ConnectionStrings>>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Configure_WithConfigMissingProvider_SetsDefaultValue()
|
||||
{
|
||||
var result = GetOptions();
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(result.Value.ProviderName, Is.Not.Null);
|
||||
Assert.That(result.Value.ProviderName, Is.EqualTo(ConnectionStrings.DefaultProviderName));
|
||||
|
||||
Assert.That(result.Get(UmbracoDbDsn).ProviderName, Is.Not.Null);
|
||||
Assert.That(result.Get(UmbracoDbDsn).ProviderName, Is.EqualTo(ConnectionStrings.DefaultProviderName));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
[AutoMoqData]
|
||||
public void Configure_WithConfiguredProvider_RespectsProviderValue(
|
||||
string aConnectionString,
|
||||
string aProviderName)
|
||||
{
|
||||
var config = new Dictionary<string, string>
|
||||
{
|
||||
[$"ConnectionStrings:{UmbracoDbDsn}"] = aConnectionString,
|
||||
[$"ConnectionStrings:{UmbracoDbDsn}_ProviderName"] = aProviderName,
|
||||
};
|
||||
|
||||
var result = GetOptions(config);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(result.Value.ProviderName, Is.Not.Null);
|
||||
Assert.That(result.Value.ProviderName, Is.EqualTo(aProviderName));
|
||||
|
||||
Assert.That(result.Get(UmbracoDbDsn).ProviderName, Is.Not.Null);
|
||||
Assert.That(result.Get(UmbracoDbDsn).ProviderName, Is.EqualTo(aProviderName));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
[AutoMoqData]
|
||||
public void Configure_WithDataDirectoryPlaceholderInConnectionStringConfig_ReplacesDataDirectoryPlaceholder(
|
||||
string aDataDirectory,
|
||||
string aConnectionString,
|
||||
string aProviderName)
|
||||
{
|
||||
AppDomain.CurrentDomain.SetData("DataDirectory", aDataDirectory);
|
||||
var config = new Dictionary<string, string>
|
||||
{
|
||||
[$"ConnectionStrings:{UmbracoDbDsn}"] = $"{ConnectionStrings.DataDirectoryPlaceholder}/{aConnectionString}",
|
||||
[$"ConnectionStrings:{UmbracoDbDsn}_ProviderName"] = aProviderName,
|
||||
};
|
||||
|
||||
var result = GetOptions(config);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(result.Value.ConnectionString, Is.Not.Null);
|
||||
Assert.That(result.Value.ConnectionString, Contains.Substring($"{aDataDirectory}/{aConnectionString}"));
|
||||
|
||||
Assert.That(result.Get(UmbracoDbDsn).ConnectionString, Is.Not.Null);
|
||||
Assert.That(result.Get(UmbracoDbDsn).ConnectionString, Contains.Substring($"{aDataDirectory}/{aConnectionString}"));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,36 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Tests.UnitTests.AutoFixture;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Configuration.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class ConnectionStringsTests
|
||||
{
|
||||
[Test]
|
||||
[TestCase("", ExpectedResult = null)]
|
||||
[TestCase(null, ExpectedResult = null)]
|
||||
[TestCase(@"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;", ExpectedResult = Constants.DbProviderNames.SqlCe)]
|
||||
[TestCase(@"Server=(LocalDb)\Umbraco;Database=NetCore;Integrated Security=true", ExpectedResult = Constants.DbProviderNames.SqlServer)]
|
||||
[TestCase(@"Data Source=(LocalDb)\Umbraco;Initial Catalog=NetCore;Integrated Security=true;", ExpectedResult = Constants.DbProviderNames.SqlServer)]
|
||||
[TestCase(@"Data Source=.\SQLExpress;Integrated Security=true;AttachDbFilename=MyDataFile.mdf;", ExpectedResult = Constants.DbProviderNames.SqlServer)]
|
||||
public string ParseProviderName(string connectionString)
|
||||
public void ProviderName_WhenNotExplicitlySet_HasDefaultSet()
|
||||
{
|
||||
var connectionStrings = new ConnectionStrings
|
||||
var sut = new ConnectionStrings();
|
||||
Assert.That(sut.ProviderName, Is.EqualTo(ConnectionStrings.DefaultProviderName));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[AutoMoqData]
|
||||
public void ConnectionString_WhenSetterCalled_ReplacesDataDirectoryPlaceholder(string aDataDirectory)
|
||||
{
|
||||
AppDomain.CurrentDomain.SetData("DataDirectory", aDataDirectory);
|
||||
|
||||
var sut = new ConnectionStrings
|
||||
{
|
||||
UmbracoConnectionString = new ConfigConnectionString(Constants.System.UmbracoConnectionName, connectionString)
|
||||
ConnectionString = $"{ConnectionStrings.DataDirectoryPlaceholder}/foo"
|
||||
};
|
||||
|
||||
var actual = connectionStrings.UmbracoConnectionString;
|
||||
|
||||
Assert.AreEqual(connectionString, actual.ConnectionString);
|
||||
Assert.AreEqual(Constants.System.UmbracoConnectionName, actual.Name);
|
||||
|
||||
return connectionStrings.UmbracoConnectionString.ProviderName;
|
||||
Assert.That(sut.ConnectionString, Contains.Substring($"{aDataDirectory}/foo"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.DistributedLocking;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
@@ -27,6 +28,7 @@ using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Infrastructure.Migrations.Install;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Mappers;
|
||||
using Umbraco.Cms.Infrastructure.Scoping;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
|
||||
@@ -53,9 +55,9 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Components
|
||||
loggerFactory.CreateLogger<UmbracoDatabaseFactory>(),
|
||||
loggerFactory,
|
||||
Options.Create(globalSettings),
|
||||
Mock.Of<IOptionsMonitor<ConnectionStrings>>(x => x.CurrentValue == connectionStrings),
|
||||
Mock.Of<IOptionsMonitor<ConnectionStrings>>(x => x.Get(It.IsAny<string>()) == connectionStrings),
|
||||
new MapperCollection(() => Enumerable.Empty<BaseMapper>()),
|
||||
TestHelper.DbProviderFactoryCreator,
|
||||
Mock.Of<IDbProviderFactoryCreator>(),
|
||||
new DatabaseSchemaCreatorFactory(loggerFactory.CreateLogger<DatabaseSchemaCreator>(), loggerFactory, new UmbracoVersion(), Mock.Of<IEventAggregator>()),
|
||||
mapperCollection);
|
||||
|
||||
@@ -69,7 +71,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Components
|
||||
Mock.Of<IServiceProvider>(),
|
||||
Options.Create(new ContentSettings()));
|
||||
IEventAggregator eventAggregator = Mock.Of<IEventAggregator>();
|
||||
var scopeProvider = new ScopeProvider(f, fs, new TestOptionsMonitor<CoreDebugSettings>(coreDebug), loggerFactory, NoAppCache.Instance, eventAggregator);
|
||||
var scopeProvider = new ScopeProvider(Mock.Of<IDistributedLockingMechanismFactory>(),f , fs, new TestOptionsMonitor<CoreDebugSettings>(coreDebug), loggerFactory, NoAppCache.Instance, eventAggregator);
|
||||
|
||||
mock.Setup(x => x.GetService(typeof(ILogger))).Returns(logger);
|
||||
mock.Setup(x => x.GetService(typeof(ILogger<ComponentCollection>))).Returns(loggerFactory.CreateLogger<ComponentCollection>);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
@@ -15,7 +16,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Configuration.Models.Validati
|
||||
public void Returns_Success_ForValid_Configuration()
|
||||
{
|
||||
var validator = new GlobalSettingsValidator();
|
||||
GlobalSettings options = BuildGlobalSettings();
|
||||
var options = new GlobalSettings();
|
||||
ValidateOptionsResult result = validator.Validate("settings", options);
|
||||
Assert.True(result.Succeeded);
|
||||
}
|
||||
@@ -24,18 +25,55 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Configuration.Models.Validati
|
||||
public void Returns_Fail_For_Configuration_With_Invalid_SmtpFrom_Field()
|
||||
{
|
||||
var validator = new GlobalSettingsValidator();
|
||||
GlobalSettings options = BuildGlobalSettings(smtpEmail: "invalid");
|
||||
var options = new GlobalSettings
|
||||
{
|
||||
Smtp = new SmtpSettings
|
||||
{
|
||||
From = "invalid",
|
||||
}
|
||||
};
|
||||
|
||||
ValidateOptionsResult result = validator.Validate("settings", options);
|
||||
Assert.False(result.Succeeded);
|
||||
}
|
||||
|
||||
private static GlobalSettings BuildGlobalSettings(string smtpEmail = "test@test.com") =>
|
||||
new GlobalSettings
|
||||
[Test]
|
||||
public void Returns_Fail_For_Configuration_With_Insufficient_SqlWriteLockTimeOut()
|
||||
{
|
||||
var validator = new GlobalSettingsValidator();
|
||||
var options = new GlobalSettings
|
||||
{
|
||||
Smtp = new SmtpSettings
|
||||
{
|
||||
From = smtpEmail,
|
||||
}
|
||||
DistributedLockingWriteLockDefaultTimeout = TimeSpan.Parse("00:00:00.099")
|
||||
};
|
||||
|
||||
ValidateOptionsResult result = validator.Validate("settings", options);
|
||||
Assert.False(result.Succeeded);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Returns_Fail_For_Configuration_With_Excessive_SqlWriteLockTimeOut()
|
||||
{
|
||||
var validator = new GlobalSettingsValidator();
|
||||
var options = new GlobalSettings
|
||||
{
|
||||
DistributedLockingWriteLockDefaultTimeout = TimeSpan.Parse("00:00:21")
|
||||
};
|
||||
|
||||
ValidateOptionsResult result = validator.Validate("settings", options);
|
||||
Assert.False(result.Succeeded);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Returns_Success_For_Configuration_With_Valid_SqlWriteLockTimeOut()
|
||||
{
|
||||
var validator = new GlobalSettingsValidator();
|
||||
var options = new GlobalSettings
|
||||
{
|
||||
DistributedLockingWriteLockDefaultTimeout = TimeSpan.Parse("00:00:20")
|
||||
};
|
||||
|
||||
ValidateOptionsResult result = validator.Validate("settings", options);
|
||||
Assert.True(result.Succeeded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Extensions
|
||||
public IHostingEnvironment BuilderHostingEnvironment { get; }
|
||||
public IProfiler Profiler { get; }
|
||||
public AppCaches AppCaches { get; }
|
||||
public TBuilder WithCollectionBuilder<TBuilder>() where TBuilder : ICollectionBuilder, new() => default;
|
||||
public TBuilder WithCollectionBuilder<TBuilder>() where TBuilder : ICollectionBuilder => default;
|
||||
|
||||
public UmbracoBuildStub() => Services = new ServiceCollection();
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class ContentTypeHistoryCleanupTests
|
||||
{
|
||||
[Test]
|
||||
public void Changing_Keep_all_Makes_ContentType_Dirty()
|
||||
{
|
||||
var contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
|
||||
Assert.IsFalse(contentType.IsDirty());
|
||||
|
||||
var newValue = 2;
|
||||
contentType.HistoryCleanup.KeepAllVersionsNewerThanDays = newValue;
|
||||
Assert.IsTrue(contentType.IsDirty());
|
||||
Assert.AreEqual(newValue, contentType.HistoryCleanup.KeepAllVersionsNewerThanDays);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Changing_Keep_latest_Makes_ContentType_Dirty()
|
||||
{
|
||||
var contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
|
||||
Assert.IsFalse(contentType.IsDirty());
|
||||
|
||||
var newValue = 2;
|
||||
contentType.HistoryCleanup.KeepLatestVersionPerDayForDays = newValue;
|
||||
Assert.IsTrue(contentType.IsDirty());
|
||||
Assert.AreEqual(newValue, contentType.HistoryCleanup.KeepLatestVersionPerDayForDays);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Changing_Prevent_Cleanup_Makes_ContentType_Dirty()
|
||||
{
|
||||
var contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
|
||||
Assert.IsFalse(contentType.IsDirty());
|
||||
|
||||
var newValue = true;
|
||||
contentType.HistoryCleanup.PreventCleanup = newValue;
|
||||
Assert.IsTrue(contentType.IsDirty());
|
||||
Assert.AreEqual(newValue, contentType.HistoryCleanup.PreventCleanup);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Replacing_History_Cleanup_Registers_As_Dirty()
|
||||
{
|
||||
var contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
Assert.IsFalse(contentType.IsDirty());
|
||||
|
||||
contentType.HistoryCleanup = new HistoryCleanup();
|
||||
|
||||
Assert.IsTrue(contentType.IsDirty());
|
||||
Assert.IsTrue(contentType.IsPropertyDirty(nameof(contentType.HistoryCleanup)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Replacing_History_Cleanup_Removes_Old_Dirty_History_Properties()
|
||||
{
|
||||
var contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
|
||||
contentType.Alias = "NewValue";
|
||||
contentType.HistoryCleanup.KeepAllVersionsNewerThanDays = 2;
|
||||
|
||||
contentType.PropertyChanged += (sender, args) =>
|
||||
{
|
||||
// Ensure that property changed is only invoked for history cleanup
|
||||
Assert.AreEqual(nameof(contentType.HistoryCleanup), args.PropertyName);
|
||||
};
|
||||
|
||||
// Since we're replacing the entire HistoryCleanup the changed property is no longer dirty, the entire HistoryCleanup is
|
||||
contentType.HistoryCleanup = new HistoryCleanup();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsTrue(contentType.IsDirty());
|
||||
Assert.IsFalse(contentType.WasDirty());
|
||||
Assert.AreEqual(2, contentType.GetDirtyProperties().Count());
|
||||
Assert.IsTrue(contentType.IsPropertyDirty(nameof(contentType.HistoryCleanup)));
|
||||
Assert.IsTrue(contentType.IsPropertyDirty(nameof(contentType.Alias)));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Old_History_Cleanup_Reference_Doesnt_Make_Content_Type_Dirty()
|
||||
{
|
||||
var contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
var oldHistoryCleanup = contentType.HistoryCleanup;
|
||||
|
||||
contentType.HistoryCleanup = new HistoryCleanup();
|
||||
contentType.ResetDirtyProperties();
|
||||
contentType.ResetWereDirtyProperties();
|
||||
|
||||
oldHistoryCleanup.KeepAllVersionsNewerThanDays = 2;
|
||||
|
||||
Assert.IsFalse(contentType.IsDirty());
|
||||
Assert.IsFalse(contentType.WasDirty());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DistributedLocking;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
@@ -16,6 +17,7 @@ using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.Scoping;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Scoping
|
||||
@@ -91,6 +93,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Scoping
|
||||
eventAggregatorMock = new Mock<IEventAggregator>();
|
||||
|
||||
return new ScopeProvider(
|
||||
Mock.Of<IDistributedLockingMechanismFactory>(),
|
||||
Mock.Of<IUmbracoDatabaseFactory>(),
|
||||
fileSystems,
|
||||
new TestOptionsMonitor<CoreDebugSettings>(new CoreDebugSettings()),
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Telemetry;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
|
||||
{
|
||||
[TestFixture]
|
||||
public class SiteIdentifierServiceTests
|
||||
{
|
||||
[TestCase("0F1785C5-7BA0-4C52-AB62-863BD2C8F3FE", true)]
|
||||
[TestCase("This is not a guid", false)]
|
||||
[TestCase("", false)]
|
||||
[TestCase("00000000-0000-0000-0000-000000000000", false)] // Don't count empty GUID as valid
|
||||
public void TryGetOnlyPassesIfValidId(string guidString, bool shouldSucceed)
|
||||
{
|
||||
var globalSettings = CreateGlobalSettings(guidString);
|
||||
var sut = new SiteIdentifierService(
|
||||
globalSettings,
|
||||
Mock.Of<IConfigManipulator>(),
|
||||
Mock.Of<ILogger<SiteIdentifierService>>());
|
||||
|
||||
var result = sut.TryGetSiteIdentifier(out var siteIdentifier);
|
||||
|
||||
Assert.AreEqual(shouldSucceed, result);
|
||||
if (shouldSucceed)
|
||||
{
|
||||
// When toString is called on a GUID it will to lower, so do the same to our guidString
|
||||
Assert.AreEqual(guidString.ToLower(), siteIdentifier.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.AreEqual(Guid.Empty, siteIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase("0F1785C5-7BA0-4C52-AB62-863BD2C8F3FE", false)]
|
||||
[TestCase("This is not a guid", true)]
|
||||
[TestCase("", true)]
|
||||
[TestCase("00000000-0000-0000-0000-000000000000", true)] // Don't count empty GUID as valid
|
||||
public void TryGetOrCreateOnlyCreatesNewGuidIfCurrentIsMissingOrInvalid(string guidString, bool shouldCreate)
|
||||
{
|
||||
var globalSettings = CreateGlobalSettings(guidString);
|
||||
var configManipulatorMock = new Mock<IConfigManipulator>();
|
||||
|
||||
var sut = new SiteIdentifierService(
|
||||
globalSettings,
|
||||
configManipulatorMock.Object,
|
||||
Mock.Of<ILogger<SiteIdentifierService>>());
|
||||
|
||||
var result = sut.TryGetOrCreateSiteIdentifier(out var identifier);
|
||||
|
||||
if (shouldCreate)
|
||||
{
|
||||
configManipulatorMock.Verify(x => x.SetGlobalId(It.IsAny<string>()), Times.Once);
|
||||
Assert.AreNotEqual(Guid.Empty, identifier);
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
configManipulatorMock.Verify(x => x.SetGlobalId(It.IsAny<string>()), Times.Never());
|
||||
Assert.AreEqual(guidString.ToLower(), identifier.ToString());
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
}
|
||||
|
||||
private IOptionsMonitor<GlobalSettings> CreateGlobalSettings(string guidString)
|
||||
{
|
||||
var globalSettings = new GlobalSettings { Id = guidString };
|
||||
return Mock.Of<IOptionsMonitor<GlobalSettings>>(x => x.CurrentValue == globalSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,36 +15,36 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
|
||||
[TestFixture]
|
||||
public class TelemetryServiceTests
|
||||
{
|
||||
[TestCase("0F1785C5-7BA0-4C52-AB62-863BD2C8F3FE", true)]
|
||||
[TestCase("This is not a guid", false)]
|
||||
[TestCase("", false)]
|
||||
public void OnlyParsesIfValidId(string guidString, bool shouldSucceed)
|
||||
[Test]
|
||||
public void UsesGetOrCreateSiteId()
|
||||
{
|
||||
var globalSettings = CreateGlobalSettings(guidString);
|
||||
var version = CreateUmbracoVersion(9, 1, 1);
|
||||
var sut = new TelemetryService(globalSettings, Mock.Of<IManifestParser>(), version);
|
||||
var version = CreateUmbracoVersion(9, 3, 1);
|
||||
var siteIdentifierServiceMock = new Mock<ISiteIdentifierService>();
|
||||
var sut = new TelemetryService(Mock.Of<IManifestParser>(), version, siteIdentifierServiceMock.Object);
|
||||
Guid guid;
|
||||
|
||||
var result = sut.TryGetTelemetryReportData(out var telemetryReportData);
|
||||
siteIdentifierServiceMock.Verify(x => x.TryGetOrCreateSiteIdentifier(out guid), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SkipsIfCantGetOrCreateId()
|
||||
{
|
||||
var version = CreateUmbracoVersion(9, 3, 1);
|
||||
var sut = new TelemetryService(Mock.Of<IManifestParser>(), version, createSiteIdentifierService(false));
|
||||
|
||||
var result = sut.TryGetTelemetryReportData(out var telemetry);
|
||||
|
||||
Assert.AreEqual(shouldSucceed, result);
|
||||
if (shouldSucceed)
|
||||
{
|
||||
// When toString is called on a GUID it will to lower, so do the same to our guidString
|
||||
Assert.AreEqual(guidString.ToLower(), telemetry.Id.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsNull(telemetry);
|
||||
}
|
||||
Assert.IsFalse(result);
|
||||
Assert.IsNull(telemetry);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReturnsSemanticVersionWithoutBuild()
|
||||
{
|
||||
var globalSettings = CreateGlobalSettings();
|
||||
var version = CreateUmbracoVersion(9, 1, 1, "-rc", "-ad2f4k2d");
|
||||
|
||||
var sut = new TelemetryService(globalSettings, Mock.Of<IManifestParser>(), version);
|
||||
var sut = new TelemetryService(Mock.Of<IManifestParser>(), version, createSiteIdentifierService());
|
||||
|
||||
var result = sut.TryGetTelemetryReportData(out var telemetry);
|
||||
|
||||
@@ -55,7 +55,6 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
|
||||
[Test]
|
||||
public void CanGatherPackageTelemetry()
|
||||
{
|
||||
var globalSettings = CreateGlobalSettings();
|
||||
var version = CreateUmbracoVersion(9, 1, 1);
|
||||
var versionPackageName = "VersionPackage";
|
||||
var packageVersion = "1.0.0";
|
||||
@@ -66,7 +65,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
|
||||
new () { PackageName = noVersionPackageName }
|
||||
};
|
||||
var manifestParser = CreateManifestParser(manifests);
|
||||
var sut = new TelemetryService(globalSettings, manifestParser, version);
|
||||
var sut = new TelemetryService(manifestParser, version, createSiteIdentifierService());
|
||||
|
||||
var success = sut.TryGetTelemetryReportData(out var telemetry);
|
||||
|
||||
@@ -87,15 +86,14 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
|
||||
[Test]
|
||||
public void RespectsAllowPackageTelemetry()
|
||||
{
|
||||
var globalSettings = CreateGlobalSettings();
|
||||
var version = CreateUmbracoVersion(9, 1, 1);
|
||||
PackageManifest[] manifests =
|
||||
{
|
||||
new () { PackageName = "DoNotTrack", AllowPackageTelemetry = false },
|
||||
new () { PackageName = "TrackingAllowed", AllowPackageTelemetry = true }
|
||||
new () { PackageName = "TrackingAllowed", AllowPackageTelemetry = true },
|
||||
};
|
||||
var manifestParser = CreateManifestParser(manifests);
|
||||
var sut = new TelemetryService(globalSettings, manifestParser, version);
|
||||
var sut = new TelemetryService(manifestParser, version, createSiteIdentifierService());
|
||||
|
||||
var success = sut.TryGetTelemetryReportData(out var telemetry);
|
||||
|
||||
@@ -121,15 +119,12 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
|
||||
return Mock.Of<IUmbracoVersion>(x => x.SemanticVersion == version);
|
||||
}
|
||||
|
||||
private IOptionsMonitor<GlobalSettings> CreateGlobalSettings(string guidString = null)
|
||||
private ISiteIdentifierService createSiteIdentifierService(bool shouldSucceed = true)
|
||||
{
|
||||
if (guidString is null)
|
||||
{
|
||||
guidString = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
var globalSettings = new GlobalSettings { Id = guidString };
|
||||
return Mock.Of<IOptionsMonitor<GlobalSettings>>(x => x.CurrentValue == globalSettings);
|
||||
var mock = new Mock<ISiteIdentifierService>();
|
||||
var siteIdentifier = shouldSucceed ? Guid.NewGuid() : Guid.Empty;
|
||||
mock.Setup(x => x.TryGetOrCreateSiteIdentifier(out siteIdentifier)).Returns(shouldSucceed);
|
||||
return mock.Object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Runtime;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Sync;
|
||||
@@ -108,6 +111,11 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.HostedServices
|
||||
|
||||
var mockServerMessenger = new Mock<IServerMessenger>();
|
||||
|
||||
var mockScopeProvider = new Mock<IScopeProvider>();
|
||||
mockScopeProvider
|
||||
.Setup(x => x.CreateScope(It.IsAny<IsolationLevel>(), It.IsAny<RepositoryCacheMode>(), It.IsAny<IScopedNotificationPublisher>(), It.IsAny<bool?>(), It.IsAny<bool>(), It.IsAny<bool>()))
|
||||
.Returns(Mock.Of<IScope>());
|
||||
|
||||
return new ScheduledPublishing(
|
||||
mockRunTimeState.Object,
|
||||
mockMainDom.Object,
|
||||
@@ -115,7 +123,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.HostedServices
|
||||
_mockContentService.Object,
|
||||
mockUmbracoContextFactory.Object,
|
||||
_mockLogger.Object,
|
||||
mockServerMessenger.Object);
|
||||
mockServerMessenger.Object,
|
||||
mockScopeProvider.Object);
|
||||
}
|
||||
|
||||
private void VerifyScheduledPublishingNotPerformed() => VerifyScheduledPublishingPerformed(Times.Never());
|
||||
|
||||
@@ -186,10 +186,13 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Logging
|
||||
|
||||
[TestCase("", 102)]
|
||||
[TestCase("Has(@Exception)", 1)]
|
||||
[TestCase("Has(@x)", 1)]
|
||||
[TestCase("Has(Duration) and Duration > 1000", 2)]
|
||||
[TestCase("Not(@Level = 'Verbose') and Not(@Level= 'Debug')", 45)]
|
||||
[TestCase("Not(@Level = 'Verbose') and Not(@Level = 'Debug')", 45)]
|
||||
[TestCase("Not(@l = 'Verbose') and Not(@l = 'Debug')", 45)]
|
||||
[TestCase("StartsWith(SourceContext, 'Umbraco.Core')", 86)]
|
||||
[TestCase("@MessageTemplate = '{EndMessage} ({Duration}ms) [Timing {TimingId}]'", 26)]
|
||||
[TestCase("@mt = '{EndMessage} ({Duration}ms) [Timing {TimingId}]'", 26)]
|
||||
[TestCase("SortedComponentTypes[?] = 'Umbraco.Web.Search.ExamineComponent'", 1)]
|
||||
[TestCase("Contains(SortedComponentTypes[?], 'DatabaseServer')", 1)]
|
||||
[Test]
|
||||
|
||||
@@ -20,6 +20,7 @@ using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.SqlSyntax;
|
||||
using Umbraco.Cms.Infrastructure.Scoping;
|
||||
using Umbraco.Cms.Persistence.SqlServer.Services;
|
||||
using Umbraco.Cms.Tests.Common.TestHelpers;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
@@ -19,6 +19,7 @@ using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.SqlSyntax;
|
||||
using Umbraco.Cms.Infrastructure.Scoping;
|
||||
using Umbraco.Cms.Persistence.SqlServer.Services;
|
||||
using Umbraco.Cms.Tests.Common.TestHelpers;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Migrations
|
||||
|
||||
@@ -9,6 +9,7 @@ using System.Data.Common;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Persistence.SqlServer.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Persistence
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@ using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Mappers;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.SqlSyntax;
|
||||
using Umbraco.Cms.Persistence.SqlServer.Services;
|
||||
using Umbraco.Cms.Tests.Common.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ using Umbraco.Cms.Infrastructure.Persistence.Dtos;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Querying;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.SqlSyntax;
|
||||
using Umbraco.Cms.Infrastructure.Serialization;
|
||||
using Umbraco.Cms.Persistence.SqlServer.Services;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Querying
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Infrastructure.Migrations.Install;
|
||||
using Umbraco.Cms.Core.Install.Models;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Persistence.SqlServer.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Persistence
|
||||
{
|
||||
[TestFixture]
|
||||
public class DatabaseContextTests
|
||||
public class SqlAzureDatabaseProviderMetadataTests
|
||||
{
|
||||
|
||||
[TestCase("MyServer", "MyDatabase", "MyUser", "MyPassword")]
|
||||
[TestCase("MyServer", "MyDatabase", "MyUser@MyServer", "MyPassword")]
|
||||
[TestCase("tcp:MyServer", "MyDatabase", "MyUser", "MyPassword")]
|
||||
@@ -19,7 +20,13 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Persistence
|
||||
[TestCase("tcp:MyServer.database.windows.net,1433", "MyDatabase", "MyUser@MyServer", "MyPassword")]
|
||||
public void Build_Azure_Connection_String_Regular(string server, string databaseName, string userName, string password)
|
||||
{
|
||||
var connectionString = DatabaseBuilder.GetAzureConnectionString(server, databaseName, userName, password);
|
||||
var settings = new DatabaseModel
|
||||
{
|
||||
Server = server, DatabaseName = databaseName, Login = userName, Password = password
|
||||
};
|
||||
|
||||
var sut = new SqlAzureDatabaseProviderMetadata();
|
||||
var connectionString = sut.GenerateConnectionString(settings);
|
||||
Assert.AreEqual(connectionString, "Server=tcp:MyServer.database.windows.net,1433;Database=MyDatabase;User ID=MyUser@MyServer;Password=MyPassword");
|
||||
}
|
||||
|
||||
@@ -29,7 +36,13 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Persistence
|
||||
[TestCase("tcp:kzeej5z8ty.ssmsawacluster4.windowsazure.mscds.com", "MyDatabase", "MyUser@kzeej5z8ty", "MyPassword")]
|
||||
public void Build_Azure_Connection_String_CustomServer(string server, string databaseName, string userName, string password)
|
||||
{
|
||||
var connectionString = DatabaseBuilder.GetAzureConnectionString(server, databaseName, userName, password);
|
||||
var settings = new DatabaseModel
|
||||
{
|
||||
Server = server, DatabaseName = databaseName, Login = userName, Password = password
|
||||
};
|
||||
|
||||
var sut = new SqlAzureDatabaseProviderMetadata();
|
||||
var connectionString = sut.GenerateConnectionString(settings);
|
||||
Assert.AreEqual(connectionString, "Server=tcp:kzeej5z8ty.ssmsawacluster4.windowsazure.mscds.com,1433;Database=MyDatabase;User ID=MyUser@kzeej5z8ty;Password=MyPassword");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using AutoFixture.NUnit3;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Infrastructure.Runtime;
|
||||
using Umbraco.Cms.Tests.UnitTests.AutoFixture;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Runtime
|
||||
{
|
||||
[TestFixture]
|
||||
internal class DefaultMainDomKeyGeneratorTests
|
||||
{
|
||||
[Test]
|
||||
[AutoMoqData]
|
||||
public void GenerateKey_WithConfiguredDiscriminatorValue_AltersHash(
|
||||
[Frozen] IHostingEnvironment hostingEnvironment,
|
||||
[Frozen] GlobalSettings globalSettings,
|
||||
[Frozen] IOptionsMonitor<GlobalSettings> globalSettingsMonitor,
|
||||
DefaultMainDomKeyGenerator sut,
|
||||
string aDiscriminator)
|
||||
{
|
||||
var withoutDiscriminator = sut.GenerateKey();
|
||||
globalSettings.MainDomKeyDiscriminator = aDiscriminator;
|
||||
var withDiscriminator = sut.GenerateKey();
|
||||
|
||||
Assert.AreNotEqual(withoutDiscriminator, withDiscriminator);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[AutoMoqData]
|
||||
public void GenerateKey_WithUnchangedDiscriminatorValue_ReturnsSameValue(
|
||||
[Frozen] IHostingEnvironment hostingEnvironment,
|
||||
[Frozen] GlobalSettings globalSettings,
|
||||
[Frozen] IOptionsMonitor<GlobalSettings> globalSettingsMonitor,
|
||||
DefaultMainDomKeyGenerator sut,
|
||||
string aDiscriminator)
|
||||
{
|
||||
globalSettings.MainDomKeyDiscriminator = aDiscriminator;
|
||||
|
||||
var a = sut.GenerateKey();
|
||||
var b = sut.GenerateKey();
|
||||
|
||||
Assert.AreEqual(a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DistributedLocking;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
@@ -18,7 +19,9 @@ using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.SqlSyntax;
|
||||
using Umbraco.Cms.Infrastructure.Scoping;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Cms.Tests.UnitTests.AutoFixture;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
{
|
||||
@@ -30,7 +33,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
/// </summary>
|
||||
/// <param name="syntaxProviderMock">The mock of the ISqlSyntaxProvider2, used to count method calls.</param>
|
||||
/// <returns></returns>
|
||||
private ScopeProvider GetScopeProvider(out Mock<ISqlSyntaxProvider> syntaxProviderMock)
|
||||
private ScopeProvider GetScopeProvider(out Mock<IDistributedLockingMechanism> lockingMechanism)
|
||||
{
|
||||
var loggerFactory = NullLoggerFactory.Instance;
|
||||
var fileSystems = new FileSystems(loggerFactory,
|
||||
@@ -45,7 +48,16 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
var databaseFactory = new Mock<IUmbracoDatabaseFactory>();
|
||||
var database = new Mock<IUmbracoDatabase>();
|
||||
var sqlContext = new Mock<ISqlContext>();
|
||||
syntaxProviderMock = new Mock<ISqlSyntaxProvider>();
|
||||
|
||||
lockingMechanism = new Mock<IDistributedLockingMechanism>();
|
||||
lockingMechanism.Setup(x => x.ReadLock(It.IsAny<int>(), It.IsAny<TimeSpan?>()))
|
||||
.Returns(Mock.Of<IDistributedLock>());
|
||||
lockingMechanism.Setup(x => x.WriteLock(It.IsAny<int>(), It.IsAny<TimeSpan?>()))
|
||||
.Returns(Mock.Of<IDistributedLock>());
|
||||
|
||||
var lockingMechanismFactory = new Mock<IDistributedLockingMechanismFactory>();
|
||||
lockingMechanismFactory.Setup(x => x.DistributedLockingMechanism)
|
||||
.Returns(lockingMechanism.Object);
|
||||
|
||||
// Setup mock of database factory to return mock of database.
|
||||
databaseFactory.Setup(x => x.CreateDatabase()).Returns(database.Object);
|
||||
@@ -54,10 +66,12 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
// Setup mock of database to return mock of sql SqlContext
|
||||
database.Setup(x => x.SqlContext).Returns(sqlContext.Object);
|
||||
|
||||
var syntaxProviderMock = new Mock<ISqlSyntaxProvider>();
|
||||
// Setup mock of ISqlContext to return syntaxProviderMock
|
||||
sqlContext.Setup(x => x.SqlSyntax).Returns(syntaxProviderMock.Object);
|
||||
|
||||
return new ScopeProvider(
|
||||
lockingMechanismFactory.Object,
|
||||
databaseFactory.Object,
|
||||
fileSystems,
|
||||
new TestOptionsMonitor<CoreDebugSettings>(new CoreDebugSettings()),
|
||||
@@ -125,8 +139,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
outerScope.Complete();
|
||||
}
|
||||
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(It.IsAny<IDatabase>(), Constants.Locks.Domains), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(It.IsAny<IDatabase>(), Constants.Locks.Languages), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(Constants.Locks.Domains, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(Constants.Locks.Languages, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -149,8 +163,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
outerScope.Complete();
|
||||
}
|
||||
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(It.IsAny<IDatabase>(), Constants.Locks.Languages), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(It.IsAny<IDatabase>(), Constants.Locks.ContentTree), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(Constants.Locks.Languages, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(Constants.Locks.ContentTree, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -181,8 +195,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
outerScope.Complete();
|
||||
}
|
||||
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(It.IsAny<IDatabase>(), timeout, Constants.Locks.Domains), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(It.IsAny<IDatabase>(), timeout, Constants.Locks.Languages), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(Constants.Locks.Domains, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.WriteLock(Constants.Locks.Languages, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -214,8 +228,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
outerScope.Complete();
|
||||
}
|
||||
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(It.IsAny<IDatabase>(), Constants.Locks.Domains), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(It.IsAny<IDatabase>(), Constants.Locks.Languages), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(Constants.Locks.Domains, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(Constants.Locks.Languages, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -248,8 +262,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
outerScope.Complete();
|
||||
}
|
||||
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(It.IsAny<IDatabase>(), timeOut, Constants.Locks.Domains), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(It.IsAny<IDatabase>(), timeOut, Constants.Locks.Languages), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(Constants.Locks.Domains, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(Constants.Locks.Languages, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -272,8 +286,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
outerScope.Complete();
|
||||
}
|
||||
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(It.IsAny<IDatabase>(), Constants.Locks.Languages), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(It.IsAny<IDatabase>(), Constants.Locks.ContentTree), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(Constants.Locks.Languages, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
syntaxProviderMock.Verify(x => x.ReadLock(Constants.Locks.ContentTree, It.IsAny<TimeSpan?>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -467,7 +481,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
public void WriteLock_Doesnt_Increment_On_Error()
|
||||
{
|
||||
var scopeProvider = GetScopeProvider(out var syntaxProviderMock);
|
||||
syntaxProviderMock.Setup(x => x.WriteLock(It.IsAny<IDatabase>(), It.IsAny<int[]>())).Throws(new Exception("Boom"));
|
||||
syntaxProviderMock.Setup(x => x.WriteLock(It.IsAny<int>(), It.IsAny<TimeSpan?>())).Throws(new Exception("Boom"));
|
||||
|
||||
using (var scope = (Scope)scopeProvider.CreateScope())
|
||||
{
|
||||
@@ -481,7 +495,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping
|
||||
public void ReadLock_Doesnt_Increment_On_Error()
|
||||
{
|
||||
var scopeProvider = GetScopeProvider(out var syntaxProviderMock);
|
||||
syntaxProviderMock.Setup(x => x.ReadLock(It.IsAny<IDatabase>(), It.IsAny<int[]>())).Throws(new Exception("Boom"));
|
||||
syntaxProviderMock.Setup(x => x.ReadLock(It.IsAny<int>(), It.IsAny<TimeSpan?>())).Throws(new Exception("Boom"));
|
||||
|
||||
using (var scope = (Scope)scopeProvider.CreateScope())
|
||||
{
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
using AutoFixture.NUnit3;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models.Membership;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Serialization;
|
||||
using Umbraco.Cms.Tests.UnitTests.AutoFixture;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
|
||||
{
|
||||
[TestFixture]
|
||||
public class UmbracoPasswordHasherTests
|
||||
{
|
||||
// Technically MD5, HMACSHA384 & HMACSHA512 were also possible but opt in as opposed to historic defaults.
|
||||
[Test]
|
||||
[InlineAutoMoqData("HMACSHA256", "Umbraco9Rocks!", "uB/pLEhhe1W7EtWMv/pSgg==1y8+aso9+h3AKRtJXlVYeg2TZKJUr64hccj82ZZ7Ksk=")] // Actually HMACSHA256
|
||||
[InlineAutoMoqData("HMACSHA256", "Umbraco9Rocks!", "t0U8atXTX/efNCtTafukwZeIpr8=")] // v4 site legacy password, with incorrect algorithm specified in database actually HMACSHA1 with password used as key.
|
||||
[InlineAutoMoqData("SHA1", "Umbraco9Rocks!", "6tZGfG9NTxJJYp19Fac9og==zzRggqANxhb+CbD/VabEt8cIde8=")] // When SHA1 is set on machine key.
|
||||
public void VerifyHashedPassword_WithValidLegacyPasswordHash_ReturnsSuccessRehashNeeded(
|
||||
string algorithm,
|
||||
string providedPassword,
|
||||
string hashedPassword,
|
||||
[Frozen] IJsonSerializer jsonSerializer,
|
||||
TestUserStub aUser,
|
||||
UmbracoPasswordHasher<TestUserStub> sut)
|
||||
{
|
||||
Mock.Get(jsonSerializer)
|
||||
.Setup(x => x.Deserialize<PersistedPasswordSettings>(It.IsAny<string>()))
|
||||
.Returns(new PersistedPasswordSettings{ HashAlgorithm = algorithm });
|
||||
|
||||
var result = sut.VerifyHashedPassword(aUser, hashedPassword, providedPassword);
|
||||
|
||||
Assert.AreEqual(PasswordVerificationResult.SuccessRehashNeeded, result);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
[InlineAutoMoqData("PBKDF2.ASPNETCORE.V3", "Umbraco9Rocks!", "AQAAAAEAACcQAAAAEDCrYcnIhHKr38yuchsDu6AFqqmLNvRooKObV25GC1LC1tLY+gWGU4xNug0lc17PHA==")]
|
||||
public void VerifyHashedPassword_WithValidModernPasswordHash_ReturnsSuccess(
|
||||
string algorithm,
|
||||
string providedPassword,
|
||||
string hashedPassword,
|
||||
[Frozen] IJsonSerializer jsonSerializer,
|
||||
TestUserStub aUser,
|
||||
UmbracoPasswordHasher<TestUserStub> sut)
|
||||
{
|
||||
Mock.Get(jsonSerializer)
|
||||
.Setup(x => x.Deserialize<PersistedPasswordSettings>(It.IsAny<string>()))
|
||||
.Returns(new PersistedPasswordSettings { HashAlgorithm = algorithm });
|
||||
|
||||
var result = sut.VerifyHashedPassword(aUser, hashedPassword, providedPassword);
|
||||
|
||||
Assert.AreEqual(PasswordVerificationResult.Success, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[InlineAutoMoqData("HMACSHA256", "Umbraco9Rocks!", "aB/cDeFaBcDefAbcD/EfaB==1y8+aso9+h3AKRtJXlVYeg2TZKJUr64hccj82ZZ7Ksk=")]
|
||||
public void VerifyHashedPassword_WithIncorrectPassword_ReturnsFailed(
|
||||
string algorithm,
|
||||
string providedPassword,
|
||||
string hashedPassword,
|
||||
[Frozen] IJsonSerializer jsonSerializer,
|
||||
TestUserStub aUser,
|
||||
UmbracoPasswordHasher<TestUserStub> sut)
|
||||
{
|
||||
Mock.Get(jsonSerializer)
|
||||
.Setup(x => x.Deserialize<PersistedPasswordSettings>(It.IsAny<string>()))
|
||||
.Returns(new PersistedPasswordSettings { HashAlgorithm = algorithm });
|
||||
|
||||
var result = sut.VerifyHashedPassword(aUser, hashedPassword, providedPassword);
|
||||
|
||||
Assert.AreEqual(PasswordVerificationResult.Failed, result);
|
||||
}
|
||||
|
||||
public class TestUserStub : UmbracoIdentityUser
|
||||
{
|
||||
public TestUserStub() => PasswordConfig = "not null or empty";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Tests.Common.Builders
|
||||
.WithAlias(relationTypeAlias)
|
||||
.WithName(relationTypeName)
|
||||
.WithIsBidirectional(false)
|
||||
.WithIsDependency(true)
|
||||
.WithParentObjectType(parentObjectType)
|
||||
.WithChildObjectType(childObjectType)
|
||||
.Done()
|
||||
@@ -61,6 +62,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Tests.Common.Builders
|
||||
Assert.AreEqual(relationTypeAlias, relation.RelationType.Alias);
|
||||
Assert.AreEqual(relationTypeName, relation.RelationType.Name);
|
||||
Assert.IsFalse(relation.RelationType.IsBidirectional);
|
||||
|
||||
Assert.IsTrue((relation.RelationType as IRelationTypeWithIsDependency).IsDependency);
|
||||
Assert.AreEqual(parentObjectType, relation.RelationType.ParentObjectType);
|
||||
Assert.AreEqual(childObjectType, relation.RelationType.ChildObjectType);
|
||||
}
|
||||
|
||||
@@ -26,11 +26,12 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Tests.Common.Builders
|
||||
var parentObjectType = Guid.NewGuid();
|
||||
var childObjectType = Guid.NewGuid();
|
||||
const bool isBidirectional = true;
|
||||
const bool isDependency = true;
|
||||
|
||||
var builder = new RelationTypeBuilder();
|
||||
|
||||
// Act
|
||||
IRelationType relationType = builder
|
||||
var relationType = builder
|
||||
.WithId(id)
|
||||
.WithAlias(alias)
|
||||
.WithName(name)
|
||||
@@ -41,6 +42,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Tests.Common.Builders
|
||||
.WithParentObjectType(parentObjectType)
|
||||
.WithChildObjectType(childObjectType)
|
||||
.WithIsBidirectional(isBidirectional)
|
||||
.WithIsDependency(isDependency)
|
||||
.Build();
|
||||
|
||||
// Assert
|
||||
@@ -54,6 +56,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Tests.Common.Builders
|
||||
Assert.AreEqual(parentObjectType, relationType.ParentObjectType);
|
||||
Assert.AreEqual(childObjectType, relationType.ChildObjectType);
|
||||
Assert.AreEqual(isBidirectional, relationType.IsBidirectional);
|
||||
Assert.AreEqual(isDependency, relationType.IsDependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Web.BackOffice.Security;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.BackOffice.Security
|
||||
{
|
||||
[TestFixture]
|
||||
public class BackOfficeAuthenticationBuilderTests
|
||||
{
|
||||
[Test]
|
||||
public void EnsureBackOfficeScheme_When_Backoffice_Auth_Scheme_Expect_Updated_SignInScheme()
|
||||
{
|
||||
var scheme = $"{Constants.Security.BackOfficeExternalAuthenticationTypePrefix}test";
|
||||
var options = new RemoteAuthenticationOptions
|
||||
{
|
||||
SignInScheme = "my_cookie"
|
||||
};
|
||||
|
||||
var sut = new BackOfficeAuthenticationBuilder.EnsureBackOfficeScheme<RemoteAuthenticationOptions>();
|
||||
sut.PostConfigure(scheme, options);
|
||||
|
||||
Assert.AreEqual(options.SignInScheme, Constants.Security.BackOfficeExternalAuthenticationType);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnsureBackOfficeScheme_When_Not_Backoffice_Auth_Scheme_Expect_No_Change()
|
||||
{
|
||||
var scheme = "test";
|
||||
var options = new RemoteAuthenticationOptions
|
||||
{
|
||||
SignInScheme = "my_cookie"
|
||||
};
|
||||
|
||||
var sut = new BackOfficeAuthenticationBuilder.EnsureBackOfficeScheme<RemoteAuthenticationOptions>();
|
||||
sut.PostConfigure(scheme, options);
|
||||
|
||||
Assert.AreNotEqual(options.SignInScheme, Constants.Security.BackOfficeExternalAuthenticationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user