From 4ec8de8b2d97435bba46a3a07bd743d1591eaf9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20M=C3=A1rkus?= Date: Sat, 20 Jan 2024 12:16:20 +0100 Subject: [PATCH] Addressing warnings. --- .../Tests/BasicOrchardFeaturesTests.cs | 7 +--- Lombiq.Tests.UI.Samples/Tests/BasicTests.cs | 7 +--- .../Tests/BasicVisualVerificationTests.cs | 7 +--- .../Tests/DatabaseSnapshotTests.cs | 7 +--- Lombiq.Tests.UI.Samples/Tests/EmailTests.cs | 7 +--- .../Tests/ErrorHandlingTests.cs | 7 +--- .../Tests/InteractiveModeTests.cs | 7 +--- Lombiq.Tests.UI.Samples/Tests/MonkeyTests.cs | 7 +--- .../Tests/MultiBrowserTests.cs | 7 +--- .../Tests/SecurityScanningTests.cs | 7 +--- .../Tests/SqlServerTests.cs | 7 +--- Lombiq.Tests.UI.Samples/Tests/TenantTests.cs | 7 +--- .../Controllers/AccountController.cs | 17 +++------ .../Controllers/InteractiveModeController.cs | 7 ++-- .../Controllers/MediaCachePurgeController.cs | 9 ++--- .../NotAdminMonkeyTestingUrlFilter.cs | 6 ++-- .../SecurityScanConfiguration.cs | 31 ++++++++-------- .../FakeViewCompilerProvider.cs | 8 ++--- .../OrchardApplicationFactory.cs | 28 +++++---------- .../Services/OrchardCoreInstance.cs | 35 +++++++------------ Lombiq.Tests.UI/Services/PortLeaseManager.cs | 9 ++--- 21 files changed, 63 insertions(+), 171 deletions(-) diff --git a/Lombiq.Tests.UI.Samples/Tests/BasicOrchardFeaturesTests.cs b/Lombiq.Tests.UI.Samples/Tests/BasicOrchardFeaturesTests.cs index d72f425df..f3a3eedbf 100644 --- a/Lombiq.Tests.UI.Samples/Tests/BasicOrchardFeaturesTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/BasicOrchardFeaturesTests.cs @@ -10,13 +10,8 @@ namespace Lombiq.Tests.UI.Samples.Tests; // writing tests for your app is not really about testing Orchard itself but nevertheless it's useful to check if all // the important features like login work - keep in mind that you can break these from your own code. So, here we run // the whole test suite. -public class BasicOrchardFeaturesTests : UITestBase +public class BasicOrchardFeaturesTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { - public BasicOrchardFeaturesTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - // We could reuse the previously specified SetupHelpers.RecipeId const here but it's actually a different recipe for // this test. [Fact] diff --git a/Lombiq.Tests.UI.Samples/Tests/BasicTests.cs b/Lombiq.Tests.UI.Samples/Tests/BasicTests.cs index 1b58f4c1a..b67131669 100644 --- a/Lombiq.Tests.UI.Samples/Tests/BasicTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/BasicTests.cs @@ -11,13 +11,8 @@ namespace Lombiq.Tests.UI.Samples.Tests; // We'll see some simpler tests as a start. Each of them will teach us important concepts. -public class BasicTests : UITestBase +public class BasicTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { - public BasicTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - // Checking that everything is OK with the homepage as an anonymous user. Note the [Fact] attribute: it's necessary // for xUnit. // Note that by default, tests are run via Chrome. Check out MultiBrowserTests for samples on using other browsers. diff --git a/Lombiq.Tests.UI.Samples/Tests/BasicVisualVerificationTests.cs b/Lombiq.Tests.UI.Samples/Tests/BasicVisualVerificationTests.cs index e16857851..4cb6cf700 100644 --- a/Lombiq.Tests.UI.Samples/Tests/BasicVisualVerificationTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/BasicVisualVerificationTests.cs @@ -10,13 +10,8 @@ namespace Lombiq.Tests.UI.Samples.Tests; // In this basic test we will check visually the rendered content. -public class BasicVisualVerificationTests : UITestBase +public class BasicVisualVerificationTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { - public BasicVisualVerificationTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - // This is a very basic sample to check that the header image is what we expect and looks as we expect. For this // magic we are using the ImageSharp.Compare package. You can find more info about it here: // https://github.com/Codeuctivity/ImageSharp.Compare. This looks really simple, but there is some trap to comparing diff --git a/Lombiq.Tests.UI.Samples/Tests/DatabaseSnapshotTests.cs b/Lombiq.Tests.UI.Samples/Tests/DatabaseSnapshotTests.cs index 7134de3f5..e15c21308 100644 --- a/Lombiq.Tests.UI.Samples/Tests/DatabaseSnapshotTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/DatabaseSnapshotTests.cs @@ -11,13 +11,8 @@ namespace Lombiq.Tests.UI.Samples.Tests; // and use that, because we don't have a pre-beaked database. Normally this feature is used to run tests when there is // an already existing database, so you don't need to take a snapshot before using the // "ExecuteTestFromExistingDBAsync()" method. -public class DatabaseSnapshotTests : UITestBase +public class DatabaseSnapshotTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { - public DatabaseSnapshotTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - // Here, we set up the application, then we take a snapshot of it, then we use the // "ExecuteTestFromExistingDBAsync()" to run the test on that. Finally, we test the basic Orchard features to check // that the application was set up correctly. diff --git a/Lombiq.Tests.UI.Samples/Tests/EmailTests.cs b/Lombiq.Tests.UI.Samples/Tests/EmailTests.cs index e29877117..07f85b2b6 100644 --- a/Lombiq.Tests.UI.Samples/Tests/EmailTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/EmailTests.cs @@ -10,13 +10,8 @@ namespace Lombiq.Tests.UI.Samples.Tests; // In this test class we'll work with (wait for it!) e-mails. The UI Testing Toolbox provides services to run an SMTP // server locally that the app can use to send out e-mails, which we can then immediately check. -public class EmailTests : UITestBase +public class EmailTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { - public EmailTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - [Fact] public Task SendingTestEmailShouldWork() => ExecuteTestAfterSetupAsync( diff --git a/Lombiq.Tests.UI.Samples/Tests/ErrorHandlingTests.cs b/Lombiq.Tests.UI.Samples/Tests/ErrorHandlingTests.cs index 3caac9265..a468a9d26 100644 --- a/Lombiq.Tests.UI.Samples/Tests/ErrorHandlingTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/ErrorHandlingTests.cs @@ -12,13 +12,8 @@ namespace Lombiq.Tests.UI.Samples.Tests; // Sometimes errors are expected. Let's check out what can be done with them! -public class ErrorHandlingTests : UITestBase +public class ErrorHandlingTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { - public ErrorHandlingTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - // It's easier to diagnose a test failure if you know whether an element is missing because there something is // actually missing or there was a server-side error. The below test visits a page where the action method throws an // exception. diff --git a/Lombiq.Tests.UI.Samples/Tests/InteractiveModeTests.cs b/Lombiq.Tests.UI.Samples/Tests/InteractiveModeTests.cs index b0438cd18..22daf22f9 100644 --- a/Lombiq.Tests.UI.Samples/Tests/InteractiveModeTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/InteractiveModeTests.cs @@ -14,13 +14,8 @@ namespace Lombiq.Tests.UI.Samples.Tests; // causes the test thread to wait until you've clicked on the "Continue Test" button in this tab. During that time you // can interact with OC as if it was a normal execution. // Note: this extension depends on Lombiq.Tests.UI.Shortcuts being enabled in your OC app. -public class InteractiveModeTests : UITestBase +public class InteractiveModeTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { - public InteractiveModeTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - // If you want to try it out yourself, just remove the "Skip" parameter and run this test. [Fact(Skip = "Use this to test to try out the interactive mode. This is not a real test you can run in CI.")] [SuppressMessage("Usage", "xUnit1004:Test methods should not be skipped", Justification = "Only a demo.")] diff --git a/Lombiq.Tests.UI.Samples/Tests/MonkeyTests.cs b/Lombiq.Tests.UI.Samples/Tests/MonkeyTests.cs index 896663c65..9bfb8e60e 100644 --- a/Lombiq.Tests.UI.Samples/Tests/MonkeyTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/MonkeyTests.cs @@ -17,13 +17,8 @@ namespace Lombiq.Tests.UI.Samples.Tests; // It's possible to execute monkey tests that walk through site pages and do random interactions with pages, like click, // scrolling, form filling, etc. Such random actions can uncover bugs that are otherwise difficult to find. Use such // tests plug holes in your test suite which are not covered by explicit tests. -public class MonkeyTests : UITestBase +public class MonkeyTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { - public MonkeyTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - // The basic idea is that you unleash monkey testing on specific pages or sections of the site, like a contact form // or the content management UI. First, we test a single page. [Fact] diff --git a/Lombiq.Tests.UI.Samples/Tests/MultiBrowserTests.cs b/Lombiq.Tests.UI.Samples/Tests/MultiBrowserTests.cs index c410f92be..fea2ed469 100644 --- a/Lombiq.Tests.UI.Samples/Tests/MultiBrowserTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/MultiBrowserTests.cs @@ -11,13 +11,8 @@ namespace Lombiq.Tests.UI.Samples.Tests; // Up until now, all of our tests were run via Chrome. However, it's important that you can run tests with any of the // other supported browsers too, even running a test with all of them at once! This class shows you how. -public class MultiBrowserTests : UITestBase +public class MultiBrowserTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { - public MultiBrowserTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - // Remember that back in BasicTests we had AnonymousHomePageShouldExist()? We have similar super-simple tests here, // just demonstrating how to drive different browsers. diff --git a/Lombiq.Tests.UI.Samples/Tests/SecurityScanningTests.cs b/Lombiq.Tests.UI.Samples/Tests/SecurityScanningTests.cs index 1530fed29..b45bc1299 100644 --- a/Lombiq.Tests.UI.Samples/Tests/SecurityScanningTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/SecurityScanningTests.cs @@ -26,13 +26,8 @@ namespace Lombiq.Tests.UI.Samples.Tests; // Note that security scanning has cross-platform support, but due to the limitations of virtualization under Windows in // GitHub Actions, these tests won't work there. They'll work on a Windows desktop though. -public class SecurityScanningTests : UITestBase +public class SecurityScanningTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { - public SecurityScanningTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - // Let's see simple use case first: Running a built-in ZAP scan. // We're running one of ZAP's built-in scans, the Baseline scan. This, as the name suggests, provides some diff --git a/Lombiq.Tests.UI.Samples/Tests/SqlServerTests.cs b/Lombiq.Tests.UI.Samples/Tests/SqlServerTests.cs index f00da7769..1db962835 100644 --- a/Lombiq.Tests.UI.Samples/Tests/SqlServerTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/SqlServerTests.cs @@ -13,13 +13,8 @@ namespace Lombiq.Tests.UI.Samples.Tests; // with it, should there be any incompatibilities). Note that for this, you need an SQL Server instance running; by // default, this will be attempted under the default localhost server name. If you're using anything else, check out the // settings in SqlServerConfiguration and Docs/Configuration.md, especially if you use Docker. -public class SqlServerTests : UITestBase +public class SqlServerTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { - public SqlServerTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - // Here we have basically two of the same tests as in BasicTests but now we're using SQL Server as the site's // database. If they still work and there are no errors in the log then the app works with SQL Server too. [Fact] diff --git a/Lombiq.Tests.UI.Samples/Tests/TenantTests.cs b/Lombiq.Tests.UI.Samples/Tests/TenantTests.cs index 166cbba8f..403ba09aa 100644 --- a/Lombiq.Tests.UI.Samples/Tests/TenantTests.cs +++ b/Lombiq.Tests.UI.Samples/Tests/TenantTests.cs @@ -11,17 +11,12 @@ namespace Lombiq.Tests.UI.Samples.Tests; // You can also test multi-tenant web apps. Creating tenants on the fly is supported as well with a shortcut. If you'd // like to test the tenant creation-setup process itself, then look into using CreateNewTenantManuallyAsync() instead. -public class TenantTests : UITestBase +public class TenantTests(ITestOutputHelper testOutputHelper) : UITestBase(testOutputHelper) { private const string TestTenantName = "Test"; private const string TestTenantUrlPrefix = "test"; private const string TestTenantDisplayName = "Lombiq's OSOCE - Test Tenant"; - public TenantTests(ITestOutputHelper testOutputHelper) - : base(testOutputHelper) - { - } - [Fact] public Task CreatingTenantShouldWork() => ExecuteTestAfterSetupAsync( diff --git a/Lombiq.Tests.UI.Shortcuts/Controllers/AccountController.cs b/Lombiq.Tests.UI.Shortcuts/Controllers/AccountController.cs index e47b31eca..d141cbc86 100644 --- a/Lombiq.Tests.UI.Shortcuts/Controllers/AccountController.cs +++ b/Lombiq.Tests.UI.Shortcuts/Controllers/AccountController.cs @@ -8,31 +8,22 @@ namespace Lombiq.Tests.UI.Shortcuts.Controllers; [DevelopmentAndLocalhostOnly] -public class AccountController : Controller +public class AccountController(UserManager userManager, SignInManager userSignInManager) : Controller { - private readonly UserManager _userManager; - private readonly SignInManager _userSignInManager; - - public AccountController(UserManager userManager, SignInManager userSignInManager) - { - _userManager = userManager; - _userSignInManager = userSignInManager; - } - [AllowAnonymous] public async Task SignInDirectly(string userName) { if (string.IsNullOrWhiteSpace(userName)) userName = "admin"; - if (await _userManager.FindByNameAsync(userName) is not { } user) return NotFound(); + if (await userManager.FindByNameAsync(userName) is not { } user) return NotFound(); - await _userSignInManager.SignInAsync(user, isPersistent: false); + await userSignInManager.SignInAsync(user, isPersistent: false); return Ok(); } public async Task SignOutDirectly() { - await _userSignInManager.SignOutAsync(); + await userSignInManager.SignOutAsync(); return Ok(); } diff --git a/Lombiq.Tests.UI.Shortcuts/Controllers/InteractiveModeController.cs b/Lombiq.Tests.UI.Shortcuts/Controllers/InteractiveModeController.cs index d748c28cd..4fb3940ff 100644 --- a/Lombiq.Tests.UI.Shortcuts/Controllers/InteractiveModeController.cs +++ b/Lombiq.Tests.UI.Shortcuts/Controllers/InteractiveModeController.cs @@ -7,12 +7,9 @@ namespace Lombiq.Tests.UI.Shortcuts.Controllers; [AllowAnonymous] [DevelopmentAndLocalhostOnly] -public class InteractiveModeController : Controller +public class InteractiveModeController(IInteractiveModeStatusAccessor interactiveModeStatusAccessor) : Controller { - private readonly IInteractiveModeStatusAccessor _interactiveModeStatusAccessor; - - public InteractiveModeController(IInteractiveModeStatusAccessor interactiveModeStatusAccessor) => - _interactiveModeStatusAccessor = interactiveModeStatusAccessor; + private readonly IInteractiveModeStatusAccessor _interactiveModeStatusAccessor = interactiveModeStatusAccessor; public IActionResult Index() { diff --git a/Lombiq.Tests.UI.Shortcuts/Controllers/MediaCachePurgeController.cs b/Lombiq.Tests.UI.Shortcuts/Controllers/MediaCachePurgeController.cs index d64d56552..bc87621f7 100644 --- a/Lombiq.Tests.UI.Shortcuts/Controllers/MediaCachePurgeController.cs +++ b/Lombiq.Tests.UI.Shortcuts/Controllers/MediaCachePurgeController.cs @@ -6,16 +6,11 @@ namespace Lombiq.Tests.UI.Shortcuts.Controllers; [Feature(ShortcutsFeatureIds.MediaCachePurge)] -public class MediaCachePurgeController : Controller +public class MediaCachePurgeController(IMediaFileStoreCache mediaFileStoreCache) : Controller { - private readonly IMediaFileStoreCache _mediaFileStoreCache; - - public MediaCachePurgeController(IMediaFileStoreCache mediaFileStoreCache) - => _mediaFileStoreCache = mediaFileStoreCache; - public async Task PurgeMediaCacheDirectly() { - var hasErrors = await _mediaFileStoreCache.PurgeAsync(); + var hasErrors = await mediaFileStoreCache.PurgeAsync(); return hasErrors ? StatusCode(500) : Ok(); } diff --git a/Lombiq.Tests.UI/MonkeyTesting/UrlFilters/NotAdminMonkeyTestingUrlFilter.cs b/Lombiq.Tests.UI/MonkeyTesting/UrlFilters/NotAdminMonkeyTestingUrlFilter.cs index fea654fd4..ed3b1c39d 100644 --- a/Lombiq.Tests.UI/MonkeyTesting/UrlFilters/NotAdminMonkeyTestingUrlFilter.cs +++ b/Lombiq.Tests.UI/MonkeyTesting/UrlFilters/NotAdminMonkeyTestingUrlFilter.cs @@ -6,11 +6,9 @@ namespace Lombiq.Tests.UI.MonkeyTesting.UrlFilters; /// /// URL filter that matches the URL to see if it's NOT an admin page (i.e. an URL NOT under /admin). /// -public class NotAdminMonkeyTestingUrlFilter : IMonkeyTestingUrlFilter +public class NotAdminMonkeyTestingUrlFilter(UITestContext context) : IMonkeyTestingUrlFilter { - private readonly AdminMonkeyTestingUrlFilter _adminMonkeyTestingUrlFilter; - - public NotAdminMonkeyTestingUrlFilter(UITestContext context) => _adminMonkeyTestingUrlFilter = new(context); + private readonly AdminMonkeyTestingUrlFilter _adminMonkeyTestingUrlFilter = new(context); public bool AllowUrl(UITestContext context, Uri url) => !_adminMonkeyTestingUrlFilter.AllowUrl(context, url); } diff --git a/Lombiq.Tests.UI/SecurityScanning/SecurityScanConfiguration.cs b/Lombiq.Tests.UI/SecurityScanning/SecurityScanConfiguration.cs index bbabd6e1c..e04601058 100644 --- a/Lombiq.Tests.UI/SecurityScanning/SecurityScanConfiguration.cs +++ b/Lombiq.Tests.UI/SecurityScanning/SecurityScanConfiguration.cs @@ -21,14 +21,14 @@ namespace Lombiq.Tests.UI.SecurityScanning; /// public class SecurityScanConfiguration { - private readonly List _additionalUris = new(); - private readonly List _excludedUrlRegexPatterns = new(); - private readonly List _disabledActiveScanRules = new(); - private readonly Dictionary _configuredActiveScanRules = new(); - private readonly List _disabledPassiveScanRules = new(); - private readonly List<(string Url, int Id, string RuleName)> _disabledRulesForUrls = new(); - private readonly List<(string Url, int Id, string RuleName, string Justification)> _falsePositives = new(); - private readonly List> _zapPlanModifiers = new(); + private readonly List _additionalUris = []; + private readonly List _excludedUrlRegexPatterns = []; + private readonly List _disabledActiveScanRules = []; + private readonly Dictionary _configuredActiveScanRules = []; + private readonly List _disabledPassiveScanRules = []; + private readonly List<(string Url, int Id, string RuleName)> _disabledRulesForUrls = []; + private readonly List<(string Url, int Id, string RuleName, string Justification)> _falsePositives = []; + private readonly List> _zapPlanModifiers = []; public Uri StartUri { get; private set; } public bool AjaxSpiderIsUsed { get; private set; } @@ -275,7 +275,10 @@ internal async Task ApplyToPlanAsync(YamlDocument yamlDocument, UITestContext co // pollPostData: "" } +#pragma warning disable S3878 // Arrays should not be created for params parameters + // We need to make an array here because there would be an error otherwise. yamlDocument.AddExcludePathsRegex([.. _excludedUrlRegexPatterns]); +#pragma warning restore S3878 // Arrays should not be created for params parameters foreach (var rule in _disabledActiveScanRules) yamlDocument.DisableActiveScanRule(rule.Id, rule.Name); foreach (var ruleConfiguration in _configuredActiveScanRules) @@ -293,15 +296,9 @@ internal async Task ApplyToPlanAsync(YamlDocument yamlDocument, UITestContext co foreach (var modifier in _zapPlanModifiers) await modifier(yamlDocument); } - public class ScanRule + public class ScanRule(int id, string name) { - public int Id { get; } - public string Name { get; } - - public ScanRule(int id, string name) - { - Id = id; - Name = name; - } + public int Id { get; } = id; + public string Name { get; } = name; } } diff --git a/Lombiq.Tests.UI/Services/OrchardCoreHosting/FakeViewCompilerProvider.cs b/Lombiq.Tests.UI/Services/OrchardCoreHosting/FakeViewCompilerProvider.cs index 3b2dccb9b..6e2eb05cf 100644 --- a/Lombiq.Tests.UI/Services/OrchardCoreHosting/FakeViewCompilerProvider.cs +++ b/Lombiq.Tests.UI/Services/OrchardCoreHosting/FakeViewCompilerProvider.cs @@ -5,14 +5,10 @@ namespace Lombiq.Tests.UI.Services.OrchardCoreHosting; -public class FakeViewCompilerProvider : IViewCompilerProvider +public class FakeViewCompilerProvider(IServiceProvider services) : IViewCompilerProvider { - private readonly IServiceProvider _services; - - public FakeViewCompilerProvider(IServiceProvider services) => _services = services; - public IViewCompiler GetCompiler() => - _services + services .GetServices() .FirstOrDefault() .GetCompiler(); diff --git a/Lombiq.Tests.UI/Services/OrchardCoreHosting/OrchardApplicationFactory.cs b/Lombiq.Tests.UI/Services/OrchardCoreHosting/OrchardApplicationFactory.cs index 60fee2ddf..016ef72e3 100644 --- a/Lombiq.Tests.UI/Services/OrchardCoreHosting/OrchardApplicationFactory.cs +++ b/Lombiq.Tests.UI/Services/OrchardCoreHosting/OrchardApplicationFactory.cs @@ -19,29 +19,19 @@ namespace Lombiq.Tests.UI.Services.OrchardCoreHosting; -public sealed class OrchardApplicationFactory : WebApplicationFactory, IProxyConnectionProvider +public sealed class OrchardApplicationFactory( + Action configureHost = null, + Action configuration = null, + Action configureOrchard = null) : WebApplicationFactory, IProxyConnectionProvider where TStartup : class { - private readonly Action _configureHost; - private readonly Action _configuration; - private readonly Action _configureOrchard; - private readonly List _createdStores = new(); - - public OrchardApplicationFactory( - Action configureHost = null, - Action configuration = null, - Action configureOrchard = null) - { - _configureHost = configureHost; - _configuration = configuration; - _configureOrchard = configureOrchard; - } + private readonly List _createdStores = []; public Uri BaseAddress => ClientOptions.BaseAddress; protected override IHost CreateHost(IHostBuilder builder) { - builder.ConfigureHostConfiguration(configurationBuilder => _configureHost?.Invoke(configurationBuilder)); + builder.ConfigureHostConfiguration(configurationBuilder => configureHost?.Invoke(configurationBuilder)); // This lock is to avoid parallel start of the application. // Microsoft.Extensions.Hosting.HostFactoryResolver.HostingListener.CreateHost() starts a new thread for the web // application instance which can cause issues in e.g.: @@ -86,7 +76,7 @@ protected override void ConfigureWebHost(IWebHostBuilder builder) loggingBuilder.AddNLogWeb(factory, new NLogAspNetCoreOptions { ReplaceLoggerFactory = true }); }); - _configuration?.Invoke(builder); + configuration?.Invoke(builder); } private void ConfigureTestServices(IServiceCollection services) @@ -96,13 +86,13 @@ private void ConfigureTestServices(IServiceCollection services) .ImplementationInstance as OrchardCoreBuilder ?? throw new InvalidOperationException( "Please call WebApplicationBuilder.Services.AddOrchardCms() in your Program.cs!"); - var configuration = services + var config = services .LastOrDefault(descriptor => descriptor.ServiceType == typeof(ConfigurationManager))? .ImplementationInstance as ConfigurationManager ?? throw new InvalidOperationException( $"Please add {nameof(ConfigurationManager)} instance to WebApplicationBuilder.Services in your Program.cs!"); - _configureOrchard?.Invoke(configuration, builder); + configureOrchard?.Invoke(config, builder); builder.ConfigureServices( builderServices => diff --git a/Lombiq.Tests.UI/Services/OrchardCoreInstance.cs b/Lombiq.Tests.UI/Services/OrchardCoreInstance.cs index 73dab1655..1ca9d3d59 100644 --- a/Lombiq.Tests.UI/Services/OrchardCoreInstance.cs +++ b/Lombiq.Tests.UI/Services/OrchardCoreInstance.cs @@ -45,12 +45,10 @@ static OrchardCoreInstanceCounter() /// /// A locally executing Orchard Core application. /// -public sealed class OrchardCoreInstance : IWebApplicationInstance +public sealed class OrchardCoreInstance(OrchardCoreConfiguration configuration, string contextId, ITestOutputHelper testOutputHelper) + : IWebApplicationInstance where TEntryPoint : class { - private readonly OrchardCoreConfiguration _configuration; - private readonly string _contextId; - private readonly ITestOutputHelper _testOutputHelper; private string _contentRootPath; private bool _isDisposed; private OrchardApplicationFactory _orchardApplication; @@ -59,24 +57,17 @@ public sealed class OrchardCoreInstance : IWebApplicationInstance public IServiceProvider Services => _orchardApplication?.Services; - public OrchardCoreInstance(OrchardCoreConfiguration configuration, string contextId, ITestOutputHelper testOutputHelper) - { - _configuration = configuration; - _contextId = contextId; - _testOutputHelper = testOutputHelper; - } - public async Task StartUpAsync() { var port = await OrchardCoreInstanceCounter.PortLeases.LeaseAvailableRandomPortAsync(); _url = OrchardCoreInstanceCounter.UrlPrefix + port.ToTechnicalString(); - _testOutputHelper.WriteLineTimestampedAndDebug("The generated URL for the Orchard Core instance is \"{0}\".", _url); + testOutputHelper.WriteLineTimestampedAndDebug("The generated URL for the Orchard Core instance is \"{0}\".", _url); CreateContentRootFolder(); - if (!string.IsNullOrEmpty(_configuration.SnapshotDirectoryPath) && Directory.Exists(_configuration.SnapshotDirectoryPath)) + if (!string.IsNullOrEmpty(configuration.SnapshotDirectoryPath) && Directory.Exists(configuration.SnapshotDirectoryPath)) { - FileSystem.CopyDirectory(_configuration.SnapshotDirectoryPath, _contentRootPath, overwrite: true); + FileSystem.CopyDirectory(configuration.SnapshotDirectoryPath, _contentRootPath, overwrite: true); } else { @@ -143,18 +134,18 @@ public async ValueTask DisposeAsync() private void CreateContentRootFolder() { - _contentRootPath = DirectoryPaths.GetTempSubDirectoryPath(_contextId, "App"); + _contentRootPath = DirectoryPaths.GetTempSubDirectoryPath(contextId, "App"); Directory.CreateDirectory(_contentRootPath); - _testOutputHelper.WriteLineTimestampedAndDebug("Content root path was created: {0}", _contentRootPath); + testOutputHelper.WriteLineTimestampedAndDebug("Content root path was created: {0}", _contentRootPath); } private async Task StartOrchardAppAsync() { - _testOutputHelper.WriteLineTimestampedAndDebug("Attempting to start the Orchard Core instance."); + testOutputHelper.WriteLineTimestampedAndDebug("Attempting to start the Orchard Core instance."); var arguments = new InstanceCommandLineArgumentsBuilder(); - await _configuration.BeforeAppStart + await configuration.BeforeAppStart .InvokeAsync(handler => handler(_contentRootPath, arguments)); // This is to avoid adding Razor runtime view compilation. @@ -175,7 +166,7 @@ await _configuration.BeforeAppStart _orchardApplication.ClientOptions.BaseAddress = new Uri(_reverseProxy.RootUrl); _reverseProxy.AttachConnectionProvider(_orchardApplication); - _testOutputHelper.WriteLineTimestampedAndDebug("The Orchard Core instance was started."); + testOutputHelper.WriteLineTimestampedAndDebug("The Orchard Core instance was started."); } private async Task StopOrchardAppAsync() @@ -183,12 +174,12 @@ private async Task StopOrchardAppAsync() _reverseProxy.DetachConnectionProvider(); if (_orchardApplication == null) return; - _testOutputHelper.WriteLineTimestampedAndDebug("Attempting to stop the Orchard Core instance."); + testOutputHelper.WriteLineTimestampedAndDebug("Attempting to stop the Orchard Core instance."); await _orchardApplication.DisposeAsync(); _orchardApplication = null; - _testOutputHelper.WriteLineTimestampedAndDebug("The Orchard Core instance was stopped."); + testOutputHelper.WriteLineTimestampedAndDebug("The Orchard Core instance was stopped."); return; } @@ -210,7 +201,7 @@ private async Task TakeSnapshotInnerAsync(string snapshotDirectoryPath) Directory.CreateDirectory(snapshotDirectoryPath); - await _configuration.BeforeTakeSnapshot + await configuration.BeforeTakeSnapshot .InvokeAsync(handler => handler(_contentRootPath, snapshotDirectoryPath)); FileSystem.CopyDirectory(_contentRootPath, snapshotDirectoryPath, overwrite: true); diff --git a/Lombiq.Tests.UI/Services/PortLeaseManager.cs b/Lombiq.Tests.UI/Services/PortLeaseManager.cs index fd119faf0..e895311f3 100644 --- a/Lombiq.Tests.UI/Services/PortLeaseManager.cs +++ b/Lombiq.Tests.UI/Services/PortLeaseManager.cs @@ -19,15 +19,12 @@ namespace Lombiq.Tests.UI.Services; Justification = "This is because SemaphoreSlim but it's not actually necessary to dispose in this case: " + "https://stackoverflow.com/questions/32033416/do-i-need-to-dispose-a-semaphoreslim. Making this class " + "IDisposable would need disposing static members above on app shutdown, which is unreliable.")] -public class PortLeaseManager +public class PortLeaseManager(int lowerBound, int upperBound) { - private readonly IEnumerable _availablePortsRange; - private readonly HashSet _usedPorts = new(); + private readonly IEnumerable _availablePortsRange = Enumerable.Range(lowerBound, upperBound - lowerBound); + private readonly HashSet _usedPorts = []; private readonly SemaphoreSlim _portAcquisitionLock = new(1, 1); - public PortLeaseManager(int lowerBound, int upperBound) => - _availablePortsRange = Enumerable.Range(lowerBound, upperBound - lowerBound); - public async Task LeaseAvailableRandomPortAsync() { await _portAcquisitionLock.WaitAsync();