diff --git a/Optimizely.TestContainers.Commerce.Tests/CommerceCatalogIntegrationTests.cs b/Optimizely.TestContainers.Commerce.Tests/CommerceCatalogIntegrationTests.cs new file mode 100644 index 0000000..2458faf --- /dev/null +++ b/Optimizely.TestContainers.Commerce.Tests/CommerceCatalogIntegrationTests.cs @@ -0,0 +1,68 @@ +using System.Globalization; +using EPiServer; +using EPiServer.Commerce.Catalog.ContentTypes; +using EPiServer.Core; +using EPiServer.DataAccess; +using EPiServer.Security; +using Mediachase.Commerce; +using Mediachase.Commerce.Catalog; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Optimizely.TestContainers.Commerce.Tests.Models.Commerce; +using Optimizely.TestContainers.Shared; + +namespace Optimizely.TestContainers.Commerce.Tests; + +public class CommerceCatalogIntegrationTests() : OptimizelyIntegrationTestBase(includeCommerce: true) +{ + protected override void ConfiureWebHostBuilder(IWebHostBuilder webHostBuilder) + { + webHostBuilder.UseStartup(); + } + + [Fact] + public void Can_Save_Catalog_And_Node_And_Product() + { + // Arrange + var referenceConverter = Services.GetRequiredService(); + var contentRepository = Services.GetRequiredService(); + + var rootLink = referenceConverter.GetRootLink(); + + var aliensCatalog = contentRepository.GetDefault(rootLink); + aliensCatalog.Name = "Aliens"; + aliensCatalog.DefaultCurrency = Currency.USD; + aliensCatalog.DefaultLanguage = "en"; + aliensCatalog.WeightBase = "kgs"; // From WeightBaseSelectionFactory + aliensCatalog.LengthBase = "cm"; // From LengthBaseSelectionFactory + + var alienCatalogReference = contentRepository.Save(aliensCatalog, SaveAction.Publish, AccessLevel.NoAccess); + + var aliensNode = contentRepository.GetDefault(alienCatalogReference, CultureInfo.GetCultureInfo("en")); + aliensNode.Name = "NeuralViz Aliens"; + + // Act + var aliensNodeReference = contentRepository.Save(aliensNode, SaveAction.Publish, AccessLevel.NoAccess); + + // Arrange + var testAlienProduct = contentRepository.GetDefault(aliensNodeReference, CultureInfo.GetCultureInfo("en")); + testAlienProduct.Name = "Snarbo"; + testAlienProduct.Description = new XhtmlString("

Some scary facts about Aliens!

"); + + // Act + var testAlienProductReference = contentRepository.Save(testAlienProduct, SaveAction.Publish, AccessLevel.NoAccess); + + // Assert + Assert.NotNull(aliensNodeReference); + Assert.NotNull(testAlienProductReference); + + // Act + aliensNode = contentRepository.Get(aliensNodeReference); + testAlienProduct = contentRepository.Get(testAlienProductReference); + + // Assert + Assert.Equal("Aliens", aliensCatalog.Name); + Assert.Equal("NeuralViz Aliens", aliensNode.Name); + Assert.Equal("Snarbo", testAlienProduct.Name); + } +} \ No newline at end of file diff --git a/Optimizely.TestContainers.Commerce.Tests/Models/Commerce/TestProduct.cs b/Optimizely.TestContainers.Commerce.Tests/Models/Commerce/TestProduct.cs new file mode 100644 index 0000000..de4ba17 --- /dev/null +++ b/Optimizely.TestContainers.Commerce.Tests/Models/Commerce/TestProduct.cs @@ -0,0 +1,25 @@ +using System.ComponentModel.DataAnnotations; +using EPiServer.Commerce.Catalog.ContentTypes; +using EPiServer.Commerce.Catalog.DataAnnotations; +using EPiServer.Core; +using EPiServer.DataAbstraction; +using EPiServer.DataAnnotations; + +namespace Optimizely.TestContainers.Commerce.Tests.Models.Commerce; + +[CatalogContentType( + GUID = "0B06DE9B-6AE3-40FB-909E-E718CCC260AE", + DisplayName = "Test Product", + Description = "Test product for integration tests.")] +public class TestProduct : ProductContent +{ + [Display( + Name = "Description", + GroupName = SystemTabNames.Content, + Order = 1)] + [Searchable] + [CultureSpecific] + [Tokenize] + [IncludeInDefaultSearch] + public virtual XhtmlString? Description { get; set; } +} \ No newline at end of file diff --git a/Optimizely.TestContainers.Commerce.Tests/Optimizely.TestContainers.Commerce.Tests.csproj b/Optimizely.TestContainers.Commerce.Tests/Optimizely.TestContainers.Commerce.Tests.csproj new file mode 100644 index 0000000..fc4b8b3 --- /dev/null +++ b/Optimizely.TestContainers.Commerce.Tests/Optimizely.TestContainers.Commerce.Tests.csproj @@ -0,0 +1,52 @@ + + + + net8.0 + enable + enable + false + + + + true + + + + true + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + + + PreserveNewest + + + + + + + + diff --git a/Optimizely.TestContainers.Commerce.Tests/Startup.cs b/Optimizely.TestContainers.Commerce.Tests/Startup.cs new file mode 100644 index 0000000..d82c17d --- /dev/null +++ b/Optimizely.TestContainers.Commerce.Tests/Startup.cs @@ -0,0 +1,48 @@ +using EPiServer.Cms.Shell; +using EPiServer.Cms.UI.AspNetIdentity; +using EPiServer.Scheduler; +using EPiServer.Web.Routing; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace Optimizely.TestContainers.Commerce.Tests; + +public class Startup(IWebHostEnvironment webHostingEnvironment) +{ + public void ConfigureServices(IServiceCollection services) + { + if (webHostingEnvironment.IsDevelopment()) + { + AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(webHostingEnvironment.ContentRootPath, "App_Data")); + + services.Configure(options => options.Enabled = false); + } + + services + .AddCmsAspNetIdentity() + .AddCms() + .AddCommerce() + .AddAdminUserRegistration() + .AddEmbeddedLocalization(); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseStaticFiles(); + app.UseRouting(); + app.UseAuthentication(); + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapContent(); + }); + } +} \ No newline at end of file diff --git a/Optimizely.TestContainers.Commerce.Tests/modules/_protected/CMS/CMS.zip b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/CMS/CMS.zip new file mode 100644 index 0000000..b97589c Binary files /dev/null and b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/CMS/CMS.zip differ diff --git a/Optimizely.TestContainers.Commerce.Tests/modules/_protected/Commerce/Commerce.zip b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/Commerce/Commerce.zip new file mode 100644 index 0000000..d4c2876 Binary files /dev/null and b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/Commerce/Commerce.zip differ diff --git a/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.TinyMce/EPiServer.Cms.TinyMce.zip b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.TinyMce/EPiServer.Cms.TinyMce.zip new file mode 100644 index 0000000..d6b64f1 Binary files /dev/null and b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.TinyMce/EPiServer.Cms.TinyMce.zip differ diff --git a/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.UI.Admin/EPiServer.Cms.UI.Admin.zip b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.UI.Admin/EPiServer.Cms.UI.Admin.zip new file mode 100644 index 0000000..df4bf05 Binary files /dev/null and b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.UI.Admin/EPiServer.Cms.UI.Admin.zip differ diff --git a/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.UI.Settings/EPiServer.Cms.UI.Settings.zip b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.UI.Settings/EPiServer.Cms.UI.Settings.zip new file mode 100644 index 0000000..4a7780c Binary files /dev/null and b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.UI.Settings/EPiServer.Cms.UI.Settings.zip differ diff --git a/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.UI.VisitorGroups/EPiServer.Cms.UI.VisitorGroups.zip b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.UI.VisitorGroups/EPiServer.Cms.UI.VisitorGroups.zip new file mode 100644 index 0000000..7975e47 Binary files /dev/null and b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Cms.UI.VisitorGroups/EPiServer.Cms.UI.VisitorGroups.zip differ diff --git a/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Commerce.Shell/EPiServer.Commerce.Shell.zip b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Commerce.Shell/EPiServer.Commerce.Shell.zip new file mode 100644 index 0000000..af12efd Binary files /dev/null and b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Commerce.Shell/EPiServer.Commerce.Shell.zip differ diff --git a/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Commerce.UI.Admin/EPiServer.Commerce.UI.Admin.zip b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Commerce.UI.Admin/EPiServer.Commerce.UI.Admin.zip new file mode 100644 index 0000000..2019d5f Binary files /dev/null and b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Commerce.UI.Admin/EPiServer.Commerce.UI.Admin.zip differ diff --git a/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Commerce.UI.CustomerService/EPiServer.Commerce.UI.CustomerService.zip b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Commerce.UI.CustomerService/EPiServer.Commerce.UI.CustomerService.zip new file mode 100644 index 0000000..2fe1084 Binary files /dev/null and b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/EPiServer.Commerce.UI.CustomerService/EPiServer.Commerce.UI.CustomerService.zip differ diff --git a/Optimizely.TestContainers.Commerce.Tests/modules/_protected/Shell/Shell.zip b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/Shell/Shell.zip new file mode 100644 index 0000000..daf3839 Binary files /dev/null and b/Optimizely.TestContainers.Commerce.Tests/modules/_protected/Shell/Shell.zip differ diff --git a/Optimizely.TestContainers.Shared/Optimizely.TestContainers.Shared.csproj b/Optimizely.TestContainers.Shared/Optimizely.TestContainers.Shared.csproj new file mode 100644 index 0000000..af6c1fe --- /dev/null +++ b/Optimizely.TestContainers.Shared/Optimizely.TestContainers.Shared.csproj @@ -0,0 +1,43 @@ + + + + net8.0 + enable + enable + false + + + + true + + + + true + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + PreserveNewest + + + + diff --git a/Optimizely.TestContainers.Shared/OptimizelyIntegrationTestBase.cs b/Optimizely.TestContainers.Shared/OptimizelyIntegrationTestBase.cs new file mode 100644 index 0000000..bbe4d37 --- /dev/null +++ b/Optimizely.TestContainers.Shared/OptimizelyIntegrationTestBase.cs @@ -0,0 +1,117 @@ +using EPiServer.Data; +using EPiServer.Framework; +using EPiServer.Framework.Initialization; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Testcontainers.MsSql; + +namespace Optimizely.TestContainers.Shared; + +public abstract class OptimizelyIntegrationTestBase(bool includeCommerce) : IAsyncLifetime +{ + private IHost _host = null!; + + // Since we use same container with different db names we can remove one of these :P + private MsSqlContainer _databaseContainer = null!; + + protected IServiceProvider Services { get; private set; } = null!; + + public virtual async Task InitializeAsync() + { + // Create Cms SQL Server container + var container = await CreateDatabaseContainer(); + + // Create CMS databse + var cmsDatabaseConnectionString = await CreateNamedDatabaseConnectionString(container, "Cms"); + + string? commerceDatabaseConnectionString = null; + if (includeCommerce) + { + commerceDatabaseConnectionString = await CreateNamedDatabaseConnectionString(container, "Commerce"); + } + + + // Build CMS host + _host = Host.CreateDefaultBuilder() + .ConfigureWebHostDefaults(webHostBuilder => + { + webHostBuilder + .ConfigureServices((context, services) => + { + // TODO: Only include in CMS test + // Add data importer service to setup default content for the tests + //services.AddTransient(); + + // Must be set here too for initialization to work for CMS + services.Configure(o => + { + o.SetConnectionString(cmsDatabaseConnectionString); + }); + }) + .ConfigureAppConfiguration((context, configBuilder) => + { + var testSettings = new Dictionary + { + ["ConnectionStrings:EPiServerDB"] = cmsDatabaseConnectionString, + ["ConnectionStrings:EcfSqlConnection"] = commerceDatabaseConnectionString, + }; + + configBuilder.AddInMemoryCollection(testSettings); + }); + + // To configure aps separately with Cms and Commerce Statup files in separate projects + ConfiureWebHostBuilder(webHostBuilder); + }) + .ConfigureCmsDefaults() + .Build(); + + // Run initialization engine (simulate application startup) + var initializer = _host.Services.GetRequiredService(); + if (initializer.InitializationState != InitializationState.Initialized) + initializer.Initialize(); + + Services = _host.Services; + + await _host.StartAsync(); + } + + protected abstract void ConfiureWebHostBuilder(IWebHostBuilder webHostBuilder); + + public async Task DisposeAsync() + { + await _host.StopAsync(); + + await _databaseContainer.DisposeAsync(); + } + + private async Task CreateDatabaseContainer() + { + var container = new MsSqlBuilder() + .WithImage("mcr.microsoft.com/mssql/server:2022-latest") + .WithPassword("yourStrong(!)Password") + .Build(); + + await container.StartAsync(); + + _databaseContainer = container; + + return _databaseContainer; + } + + private async Task CreateNamedDatabaseConnectionString(MsSqlContainer container, string databaseName) + { + databaseName = $"{GetType().Name}-{databaseName}"; + + var masterConnectionString = container.GetConnectionString(); + await using var connection = new SqlConnection(masterConnectionString); + await connection.OpenAsync(); + await using var command = new SqlCommand($"CREATE DATABASE [{databaseName}]", connection); + await command.ExecuteNonQueryAsync(); + + // Workaround to set separate database names inside container + return masterConnectionString.Replace("master", databaseName); + } +} \ No newline at end of file diff --git a/Optimizely.TestContainers.Shared/modules/_protected/CMS/CMS.zip b/Optimizely.TestContainers.Shared/modules/_protected/CMS/CMS.zip new file mode 100644 index 0000000..b97589c Binary files /dev/null and b/Optimizely.TestContainers.Shared/modules/_protected/CMS/CMS.zip differ diff --git a/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.TinyMce/EPiServer.Cms.TinyMce.zip b/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.TinyMce/EPiServer.Cms.TinyMce.zip new file mode 100644 index 0000000..d6b64f1 Binary files /dev/null and b/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.TinyMce/EPiServer.Cms.TinyMce.zip differ diff --git a/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.UI.Admin/EPiServer.Cms.UI.Admin.zip b/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.UI.Admin/EPiServer.Cms.UI.Admin.zip new file mode 100644 index 0000000..df4bf05 Binary files /dev/null and b/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.UI.Admin/EPiServer.Cms.UI.Admin.zip differ diff --git a/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.UI.Settings/EPiServer.Cms.UI.Settings.zip b/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.UI.Settings/EPiServer.Cms.UI.Settings.zip new file mode 100644 index 0000000..4a7780c Binary files /dev/null and b/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.UI.Settings/EPiServer.Cms.UI.Settings.zip differ diff --git a/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.UI.VisitorGroups/EPiServer.Cms.UI.VisitorGroups.zip b/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.UI.VisitorGroups/EPiServer.Cms.UI.VisitorGroups.zip new file mode 100644 index 0000000..7975e47 Binary files /dev/null and b/Optimizely.TestContainers.Shared/modules/_protected/EPiServer.Cms.UI.VisitorGroups/EPiServer.Cms.UI.VisitorGroups.zip differ diff --git a/Optimizely.TestContainers.Shared/modules/_protected/Shell/Shell.zip b/Optimizely.TestContainers.Shared/modules/_protected/Shell/Shell.zip new file mode 100644 index 0000000..daf3839 Binary files /dev/null and b/Optimizely.TestContainers.Shared/modules/_protected/Shell/Shell.zip differ diff --git a/OptimizelyTestContainers.sln b/OptimizelyTestContainers.sln index fec92fe..6b963d2 100644 --- a/OptimizelyTestContainers.sln +++ b/OptimizelyTestContainers.sln @@ -1,22 +1,28 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Optimizely.TestContainers", "src\Web\Optimizely.TestContainers.csproj", "{E65E2A81-3213-498F-80B0-4C12CF2CBB6C}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptimizelyTestContainers.Tests", "test\OptimizelyTestContainers.Tests\OptimizelyTestContainers.Tests.csproj", "{60DAC0B9-1D46-4D3A-BC27-4B7BE193AB4E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Optimizely.TestContainers.Shared", "Optimizely.TestContainers.Shared\Optimizely.TestContainers.Shared.csproj", "{E4204C7A-7CC7-40FB-BFE2-D36B7286D7D3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Optimizely.TestContainers.Commerce.Tests", "Optimizely.TestContainers.Commerce.Tests\Optimizely.TestContainers.Commerce.Tests.csproj", "{63D88C12-0DF6-4C82-939C-1FF0B564B63E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E65E2A81-3213-498F-80B0-4C12CF2CBB6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E65E2A81-3213-498F-80B0-4C12CF2CBB6C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E65E2A81-3213-498F-80B0-4C12CF2CBB6C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E65E2A81-3213-498F-80B0-4C12CF2CBB6C}.Release|Any CPU.Build.0 = Release|Any CPU {60DAC0B9-1D46-4D3A-BC27-4B7BE193AB4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {60DAC0B9-1D46-4D3A-BC27-4B7BE193AB4E}.Debug|Any CPU.Build.0 = Debug|Any CPU {60DAC0B9-1D46-4D3A-BC27-4B7BE193AB4E}.Release|Any CPU.ActiveCfg = Release|Any CPU {60DAC0B9-1D46-4D3A-BC27-4B7BE193AB4E}.Release|Any CPU.Build.0 = Release|Any CPU + {E4204C7A-7CC7-40FB-BFE2-D36B7286D7D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E4204C7A-7CC7-40FB-BFE2-D36B7286D7D3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E4204C7A-7CC7-40FB-BFE2-D36B7286D7D3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E4204C7A-7CC7-40FB-BFE2-D36B7286D7D3}.Release|Any CPU.Build.0 = Release|Any CPU + {63D88C12-0DF6-4C82-939C-1FF0B564B63E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63D88C12-0DF6-4C82-939C-1FF0B564B63E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63D88C12-0DF6-4C82-939C-1FF0B564B63E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63D88C12-0DF6-4C82-939C-1FF0B564B63E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/OptimizelyTestContainers.slnx b/OptimizelyTestContainers.slnx index 066bc36..b05f6fb 100644 --- a/OptimizelyTestContainers.slnx +++ b/OptimizelyTestContainers.slnx @@ -1,4 +1,5 @@ - + + - + \ No newline at end of file diff --git a/src/Web/nuget.config b/nuget.config similarity index 93% rename from src/Web/nuget.config rename to nuget.config index 79187e1..10e45c9 100644 --- a/src/Web/nuget.config +++ b/nuget.config @@ -5,4 +5,4 @@ - + \ No newline at end of file diff --git a/src/Web/.gitignore b/src/Web/.gitignore deleted file mode 100644 index a3fc9be..0000000 --- a/src/Web/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -App_Data/ -node_modules/ -artifacts/ - -# Visual Studio files -*.user -*.lock.json -.vscode/ -.vs/ -.nuget/ -packages/ -bin/ -obj/ - -# Optimizely files -*license.config -modules/ - -# OS crap -.DS_Store -thumbs.db -ehthumbs.db -desktop.ini -.idea \ No newline at end of file diff --git a/src/Web/Optimizely.TestContainers.csproj b/src/Web/Optimizely.TestContainers.csproj deleted file mode 100644 index be8a83a..0000000 --- a/src/Web/Optimizely.TestContainers.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - net8.0 - enable - enable - - - true - - - true - - - - - - - - - - - - - - - - - diff --git a/src/Web/Program.cs b/src/Web/Program.cs deleted file mode 100644 index 2e1a1ff..0000000 --- a/src/Web/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Optimizely.TestContainers; - -public class Program -{ - public static void Main(string[] args) => CreateHostBuilder(args).Build().Run(); - - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureCmsDefaults() - .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup()); -} diff --git a/src/Web/Properties/launchSettings.json b/src/Web/Properties/launchSettings.json deleted file mode 100644 index 609a1de..0000000 --- a/src/Web/Properties/launchSettings.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "profiles": { - "Optimizely.TestContainers": { - "commandName": "Project", - "launchBrowser": true, - "applicationUrl": "https://localhost:5000/", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/src/Web/README.md b/src/Web/README.md deleted file mode 100644 index f7cc266..0000000 --- a/src/Web/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Empty CMS template - -## How to run - -Chose one of the following options to get started. - -### Windows - -Prerequisities -- .NET SDK 8+ -- SQL Server 2016 Express LocalDB (or later) - -```bash -$ dotnet run -```` - -### Any OS with Docker - -Prerequisities -- Docker -- Enable Docker support when applying the template -- Review the .env file and make changes where necessary to the Docker-related variables - -```bash -$ docker-compose up -```` - -> Note that this Docker setup is just configured for local development. Follow this [guide to enable HTTPS](https://github.com/dotnet/dotnet-docker/blob/main/samples/run-aspnetcore-https-development.md). - -#### Reclaiming Docker Image Space - -1. Backup the App_Data/\${DB_NAME}.mdf and App_Data/\${DB_NAME}.ldf DB restoration files for safety -2. Run `docker compose down --rmi all` to remove containers, networks, and images associated with the specific project instance -3. In the future, run `docker compose up` anytime you want to recreate the images and containers - -### Any OS with external database server - -Prerequisities -- .NET SDK 8+ -- SQL Server 2016 (or later) on a external server, e.g. Azure SQL - -Create an empty database on the external database server and update the connection string accordingly. - -```bash -$ dotnet run -```` diff --git a/src/Web/Resources/Translations/Views.xml b/src/Web/Resources/Translations/Views.xml deleted file mode 100644 index 85c4137..0000000 --- a/src/Web/Resources/Translations/Views.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/Web/appsettings.Development.json b/src/Web/appsettings.Development.json deleted file mode 100644 index a2fd5e0..0000000 --- a/src/Web/appsettings.Development.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "EPiServer": "Information", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "ConnectionStrings": { - "EPiServerDB": "Data Source=(LocalDb)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\Optimizely.TestContainers.mdf;Initial Catalog=Optimizely.TestContainers;Integrated Security=True;Connect Timeout=30" - }, - "EPiServer": { - "Cms": { - "MappedRoles": { - "Items": { - "CmsEditors": { - "MappedRoles": [ "WebEditors", "WebAdmins" ] - }, - "CmsAdmins": { - "MappedRoles": [ "WebAdmins" ] - } - } - } - } - } -} diff --git a/src/Web/appsettings.json b/src/Web/appsettings.json deleted file mode 100644 index 8f4d4da..0000000 --- a/src/Web/appsettings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Warning", - "Microsoft": "Warning", - "EPiServer": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "AllowedHosts": "*" -} \ No newline at end of file diff --git a/src/Web/Models/Media/GenericMedia.cs b/test/OptimizelyTestContainers.Tests/Models/Media/GenericMedia.cs similarity index 67% rename from src/Web/Models/Media/GenericMedia.cs rename to test/OptimizelyTestContainers.Tests/Models/Media/GenericMedia.cs index 7d8e372..1a13f03 100644 --- a/src/Web/Models/Media/GenericMedia.cs +++ b/test/OptimizelyTestContainers.Tests/Models/Media/GenericMedia.cs @@ -1,4 +1,7 @@ -namespace Optimizely.TestContainers.Models.Media; +using EPiServer.Core; +using EPiServer.DataAnnotations; + +namespace OptimizelyTestContainers.Tests.Models.Media; [ContentType(GUID = "EE3BD195-7CB0-4756-AB5F-E5E223CD9820")] public class GenericMedia : MediaData diff --git a/src/Web/Models/Media/ImageFile.cs b/test/OptimizelyTestContainers.Tests/Models/Media/ImageFile.cs similarity index 69% rename from src/Web/Models/Media/ImageFile.cs rename to test/OptimizelyTestContainers.Tests/Models/Media/ImageFile.cs index 7f0b6aa..df4e3bc 100644 --- a/src/Web/Models/Media/ImageFile.cs +++ b/test/OptimizelyTestContainers.Tests/Models/Media/ImageFile.cs @@ -1,6 +1,8 @@ -using EPiServer.Framework.DataAnnotations; +using EPiServer.Core; +using EPiServer.DataAnnotations; +using EPiServer.Framework.DataAnnotations; -namespace Optimizely.TestContainers.Models.Media; +namespace OptimizelyTestContainers.Tests.Models.Media; [ContentType(GUID = "0A89E464-56D4-449F-AEA8-2BF774AB8730")] [MediaDescriptor(ExtensionString = "jpg,jpeg,jpe,ico,gif,bmp,png")] diff --git a/src/Web/Models/Media/VideoFile.cs b/test/OptimizelyTestContainers.Tests/Models/Media/VideoFile.cs similarity index 92% rename from src/Web/Models/Media/VideoFile.cs rename to test/OptimizelyTestContainers.Tests/Models/Media/VideoFile.cs index fe3aac1..6662cc0 100644 --- a/src/Web/Models/Media/VideoFile.cs +++ b/test/OptimizelyTestContainers.Tests/Models/Media/VideoFile.cs @@ -1,4 +1,6 @@ using System.ComponentModel.DataAnnotations; +using EPiServer.Core; +using EPiServer.DataAnnotations; using EPiServer.Framework.DataAnnotations; using EPiServer.Web; diff --git a/src/Web/Models/Pages/NewsPage.cs b/test/OptimizelyTestContainers.Tests/Models/Pages/NewsPage.cs similarity index 62% rename from src/Web/Models/Pages/NewsPage.cs rename to test/OptimizelyTestContainers.Tests/Models/Pages/NewsPage.cs index 44f8fce..412db1e 100644 --- a/src/Web/Models/Pages/NewsPage.cs +++ b/test/OptimizelyTestContainers.Tests/Models/Pages/NewsPage.cs @@ -1,4 +1,7 @@ -namespace Optimizely.TestContainers.Models.Pages; +using EPiServer.Core; +using EPiServer.DataAnnotations; + +namespace OptimizelyTestContainers.Tests.Models.Pages; [ContentType( GUID = "7B873919-11AC-4DF4-B9E8-09F414F76164", diff --git a/src/Web/Models/Pages/StartPage.cs b/test/OptimizelyTestContainers.Tests/Models/Pages/StartPage.cs similarity index 75% rename from src/Web/Models/Pages/StartPage.cs rename to test/OptimizelyTestContainers.Tests/Models/Pages/StartPage.cs index 5b0137d..578fa7b 100644 --- a/src/Web/Models/Pages/StartPage.cs +++ b/test/OptimizelyTestContainers.Tests/Models/Pages/StartPage.cs @@ -1,6 +1,9 @@ using System.ComponentModel.DataAnnotations; +using EPiServer.Core; +using EPiServer.DataAbstraction; +using EPiServer.DataAnnotations; -namespace Optimizely.TestContainers.Models.Pages; +namespace OptimizelyTestContainers.Tests.Models.Pages; /// /// Used for the site's start page and also acts as a container for site settings diff --git a/test/OptimizelyTestContainers.Tests/NewsPageIntegrationTests.cs b/test/OptimizelyTestContainers.Tests/NewsPageIntegrationTests.cs index b5c81b9..5023742 100644 --- a/test/OptimizelyTestContainers.Tests/NewsPageIntegrationTests.cs +++ b/test/OptimizelyTestContainers.Tests/NewsPageIntegrationTests.cs @@ -4,13 +4,26 @@ using EPiServer.DataAccess; using EPiServer.Security; using EPiServer.Web; +using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; -using Optimizely.TestContainers.Models.Pages; +using Optimizely.TestContainers.Shared; +using OptimizelyTestContainers.Tests.Models.Pages; namespace OptimizelyTestContainers.Tests; -public class NewsPageIntegrationTest : OptimizelyIntegrationTestBase +public class NewsPageIntegrationTest() : OptimizelyIntegrationTestBase(includeCommerce: false) { + protected override void ConfiureWebHostBuilder(IWebHostBuilder webHostBuilder) + { + webHostBuilder.UseStartup(); + + webHostBuilder.ConfigureServices(services => + { + // Add data importer service to setup default content for the tests + services.AddTransient(); + }); + } + [Fact] public void Can_Create_And_Read_NewsPage() { @@ -21,6 +34,8 @@ public void Can_Create_And_Read_NewsPage() var basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!; var episerverDataFile = Path.Combine(basePath, "DefaultSiteContent.episerverdata"); var dataImporter = Services.GetRequiredService(); + + // Run data importer service to setup default content for the tests dataImporter.Import(episerverDataFile); // Find StartPage from root diff --git a/test/OptimizelyTestContainers.Tests/OptimizelyIntegrationTestBase.cs b/test/OptimizelyTestContainers.Tests/OptimizelyIntegrationTestBase.cs deleted file mode 100644 index 431c79a..0000000 --- a/test/OptimizelyTestContainers.Tests/OptimizelyIntegrationTestBase.cs +++ /dev/null @@ -1,73 +0,0 @@ -using EPiServer.Cms.Shell; -using EPiServer.Data; -using EPiServer.Framework; -using EPiServer.Framework.Initialization; -using EPiServer.Framework.Web; -using EPiServer.Web; -using EPiServer.Web.Templating; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Optimizely.TestContainers; -using Testcontainers.MsSql; - -namespace OptimizelyTestContainers.Tests; - -public class OptimizelyIntegrationTestBase : IAsyncLifetime -{ - private IHost _host = null!; - private MsSqlContainer _dbContainer = null!; - - public IServiceProvider Services { get; private set; } = null!; - - public async Task InitializeAsync() - { - // Start SQL Server container - _dbContainer = new MsSqlBuilder() - .WithImage("mcr.microsoft.com/mssql/server:2022-latest") - .WithPassword("yourStrong(!)Password") - .Build(); - - await _dbContainer.StartAsync(); - - // Build CMS host - _host = Host.CreateDefaultBuilder() - .ConfigureCmsDefaults() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.ConfigureServices((context, services) => - { - // Override connection string to use container connection - services.Configure(opt => - { - var containerConnectionString = _dbContainer.GetConnectionString(); - - opt.SetConnectionString(containerConnectionString); - }); - - // Add data importer service to setup default content for the tests - services.AddTransient(); - }); - - // Use the Alloy startup by default - webBuilder.UseStartup(); - - }) - .Build(); - - await _host.StartAsync(); - - // Run initialization engine (simulate application startup) - var initializer = _host.Services.GetRequiredService(); - if (initializer.InitializationState != InitializationState.Initialized) - initializer.Initialize(); - - Services = _host.Services; - } - - public async Task DisposeAsync() - { - await _host.StopAsync(); - await _dbContainer.DisposeAsync(); - } -} \ No newline at end of file diff --git a/test/OptimizelyTestContainers.Tests/OptimizelyTestContainers.Tests.csproj b/test/OptimizelyTestContainers.Tests/OptimizelyTestContainers.Tests.csproj index 0838d0f..5aca09c 100644 --- a/test/OptimizelyTestContainers.Tests/OptimizelyTestContainers.Tests.csproj +++ b/test/OptimizelyTestContainers.Tests/OptimizelyTestContainers.Tests.csproj @@ -35,7 +35,7 @@ - + diff --git a/src/Web/Startup.cs b/test/OptimizelyTestContainers.Tests/Startup.cs similarity index 70% rename from src/Web/Startup.cs rename to test/OptimizelyTestContainers.Tests/Startup.cs index 2722782..d6870fb 100644 --- a/src/Web/Startup.cs +++ b/test/OptimizelyTestContainers.Tests/Startup.cs @@ -1,25 +1,21 @@ using EPiServer.Cms.Shell; using EPiServer.Cms.UI.AspNetIdentity; using EPiServer.Scheduler; -using EPiServer.ServiceLocation; using EPiServer.Web.Routing; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; -namespace Optimizely.TestContainers; +namespace OptimizelyTestContainers.Tests; -public class Startup +public class Startup(IWebHostEnvironment webHostingEnvironment) { - private readonly IWebHostEnvironment _webHostingEnvironment; - - public Startup(IWebHostEnvironment webHostingEnvironment) - { - _webHostingEnvironment = webHostingEnvironment; - } - public void ConfigureServices(IServiceCollection services) { - if (_webHostingEnvironment.IsDevelopment()) + if (webHostingEnvironment.IsDevelopment()) { - AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(_webHostingEnvironment.ContentRootPath, "App_Data")); + AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(webHostingEnvironment.ContentRootPath, "App_Data")); services.Configure(options => options.Enabled = false); } diff --git a/test/OptimizelyTestContainers.Tests/nuget.config b/test/OptimizelyTestContainers.Tests/nuget.config deleted file mode 100644 index c15248a..0000000 --- a/test/OptimizelyTestContainers.Tests/nuget.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file