1- using EPiServer . Data ;
2- using EPiServer . Framework ;
1+ using EPiServer . Framework ;
32using EPiServer . Framework . Initialization ;
3+ using Mediachase . Data . Provider ;
44using Microsoft . AspNetCore . Hosting ;
5+ using Microsoft . Data . SqlClient ;
56using Microsoft . Extensions . Configuration ;
67using Microsoft . Extensions . DependencyInjection ;
78using Microsoft . Extensions . Hosting ;
@@ -14,61 +15,53 @@ public class OptimizelyIntegrationTestBase(bool includeCommerce) : IAsyncLifetim
1415{
1516 private IHost _host = null ! ;
1617
17- private MsSqlContainer _cmsDbContainer = null ! ;
18+ // Since we use same container with different db names we can remove one of these :P
19+ private MsSqlContainer _databaseContainer = null ! ;
1820
19- private MsSqlContainer _commerceDbContainer = null ! ;
20-
2121 protected IServiceProvider Services { get ; private set ; } = null ! ;
22-
22+
2323 public virtual async Task InitializeAsync ( )
2424 {
2525 // Create Cms SQL Server container
26- _cmsDbContainer = CreateNamedSqlContainer ( "Cms" ) ;
26+ var container = await CreateDatabaseContainer ( ) ;
2727
28- // Create Commerce SQL Server container
29- if ( includeCommerce )
30- {
31- _commerceDbContainer = CreateNamedSqlContainer ( "Commerce" ) ;
32- }
33-
34- // Start database containers
35- await _cmsDbContainer . StartAsync ( ) ;
28+ // Create CMS databse
29+ var cmsDatabaseConnectionString = await CreateNamedDatabaseConnectionString ( container , "Cms" ) ;
3630
31+ string ? commerceDatabaseConnectionString = null ;
3732 if ( includeCommerce )
3833 {
39- await _commerceDbContainer . StartAsync ( ) ;
34+ commerceDatabaseConnectionString = await CreateNamedDatabaseConnectionString ( container , "Commerce" ) ;
4035 }
41-
36+
37+
4238 // Build CMS host
4339 _host = Host . CreateDefaultBuilder ( )
44- . ConfigureCmsDefaults ( )
45- . ConfigureWebHostDefaults ( webHostBuilder =>
40+ . ConfigureWebHostDefaults ( webHostBuilder =>
4641 {
47- webHostBuilder . ConfigureServices ( ( context , services ) =>
48- {
49- services . Configure < DataAccessOptions > ( opt =>
42+ webHostBuilder
43+ . ConfigureServices ( ( context , services ) =>
5044 {
51- var containerConnectionString = _cmsDbContainer . GetConnectionString ( ) ;
52-
53- opt . SetConnectionString ( containerConnectionString ) ;
54- } ) ;
55-
56- // Add data importer service to setup default content for the tests
57- services . AddTransient < OptimizelyDataImporter > ( ) ;
58- } ) ;
59-
60- webHostBuilder . ConfigureAppConfiguration ( ( context , configBuilder ) =>
61- {
62- var testSettings = new Dictionary < string , string ? >
45+ // Add data importer service to setup default content for the tests
46+ services . AddTransient < OptimizelyDataImporter > ( ) ;
47+ } )
48+ . ConfigureAppConfiguration ( ( context , configBuilder ) =>
6349 {
64- // TODO: Find Constant for connection string!
65- [ "ConnectionStrings:EcfSqlConnection" ] = _commerceDbContainer . GetConnectionString ( )
66- } ;
67-
68- configBuilder . AddInMemoryCollection ( testSettings ) ;
69- } ) ;
50+ // Workaround to set separate database names inisde container
51+ if ( includeCommerce && ! string . IsNullOrWhiteSpace ( commerceDatabaseConnectionString ) )
52+ {
53+ var testSettings = new Dictionary < string , string ? >
54+ {
55+ // TODO: Find Constant for connection string!
56+ [ "ConnectionStrings:EPiServerDB" ] = cmsDatabaseConnectionString ,
57+ [ "ConnectionStrings:EcfSqlConnection" ] = commerceDatabaseConnectionString ,
58+ } ;
7059
71- if ( includeCommerce )
60+ configBuilder . AddInMemoryCollection ( testSettings ) ;
61+ }
62+ } ) ;
63+
64+ if ( includeCommerce && ! string . IsNullOrWhiteSpace ( commerceDatabaseConnectionString ) )
7265 {
7366 webHostBuilder . UseStartup < StartupWithCmsAndCommerce > ( ) ;
7467 }
@@ -78,9 +71,13 @@ public virtual async Task InitializeAsync()
7871 }
7972
8073 } )
81- . Build ( ) ;
74+ . ConfigureCmsDefaults ( )
75+ . Build ( ) ;
76+
77+ // Run initialization engine (simulate application startup)
8278
83- // Run initialization engine (simulate application startup)
79+ // TODO: Runs all initializable modules even if commerce is not included!
80+ // Solve with custom IAssemblyScanner?
8481 var initializer = _host . Services . GetRequiredService < InitializationEngine > ( ) ;
8582 if ( initializer . InitializationState != InitializationState . Initialized )
8683 initializer . Initialize ( ) ;
@@ -94,20 +91,34 @@ public async Task DisposeAsync()
9491 {
9592 await _host . StopAsync ( ) ;
9693
97- await _cmsDbContainer . DisposeAsync ( ) ;
98-
99- if ( includeCommerce )
100- {
101- await _commerceDbContainer . DisposeAsync ( ) ;
102- }
94+ await _databaseContainer . DisposeAsync ( ) ;
10395 }
10496
105- private MsSqlContainer CreateNamedSqlContainer ( string componentName )
97+ private async Task < MsSqlContainer > CreateDatabaseContainer ( )
10698 {
107- return new MsSqlBuilder ( )
108- . WithName ( componentName + GetType ( ) ) // Unique name per test class and component
99+ var container = new MsSqlBuilder ( )
109100 . WithImage ( "mcr.microsoft.com/mssql/server:2022-latest" )
110101 . WithPassword ( "yourStrong(!)Password" )
111102 . Build ( ) ;
103+
104+ await container . StartAsync ( ) ;
105+
106+ _databaseContainer = container ;
107+
108+ return _databaseContainer ;
109+ }
110+
111+ private async Task < string > CreateNamedDatabaseConnectionString ( MsSqlContainer container , string databaseName )
112+ {
113+ databaseName = $ "{ GetType ( ) . Name } -{ databaseName } ";
114+
115+ var masterConnectionString = container . GetConnectionString ( ) ;
116+ await using var connection = new SqlConnection ( masterConnectionString ) ;
117+ await connection . OpenAsync ( ) ;
118+ await using var command = new SqlCommand ( $ "CREATE DATABASE [{ databaseName } ]", connection ) ;
119+ await command . ExecuteNonQueryAsync ( ) ;
120+
121+ // Workaround to set separate database names inside container
122+ return masterConnectionString . Replace ( "master" , databaseName ) ;
112123 }
113124}
0 commit comments