Skip to content

Commit 41b8365

Browse files
Initial working sample creating a site, start page and news page below start and reading the page from a docker DB
1 parent e36f338 commit 41b8365

File tree

9 files changed

+240
-39
lines changed

9 files changed

+240
-39
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace Optimizely.TestContainers.Models.Media;
2+
3+
[ContentType(GUID = "EE3BD195-7CB0-4756-AB5F-E5E223CD9820")]
4+
public class GenericMedia : MediaData
5+
{
6+
/// <summary>
7+
/// Gets or sets the description.
8+
/// </summary>
9+
public virtual String Description { get; set; }
10+
}

src/Web/Models/Media/ImageFile.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using EPiServer.Framework.DataAnnotations;
2+
3+
namespace Optimizely.TestContainers.Models.Media;
4+
5+
[ContentType(GUID = "0A89E464-56D4-449F-AEA8-2BF774AB8730")]
6+
[MediaDescriptor(ExtensionString = "jpg,jpeg,jpe,ico,gif,bmp,png")]
7+
public class ImageFile : ImageData
8+
{
9+
/// <summary>
10+
/// Gets or sets the copyright.
11+
/// </summary>
12+
/// <value>
13+
/// The copyright.
14+
/// </value>
15+
public virtual string Copyright { get; set; }
16+
}

src/Web/Models/Media/VideoFile.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.ComponentModel.DataAnnotations;
2+
using EPiServer.Framework.DataAnnotations;
3+
using EPiServer.Web;
4+
5+
namespace Optimizely.TestContainers.Models.Media;
6+
7+
[ContentType(GUID = "85468104-E06F-47E5-A317-FC9B83D3CBA6")]
8+
[MediaDescriptor(ExtensionString = "flv,mp4,webm")]
9+
public class VideoFile : VideoData
10+
{
11+
/// <summary>
12+
/// Gets or sets the copyright.
13+
/// </summary>
14+
public virtual string Copyright { get; set; }
15+
16+
/// <summary>
17+
/// Gets or sets the URL to the preview image.
18+
/// </summary>
19+
[UIHint(UIHint.Image)]
20+
public virtual ContentReference PreviewImage { get; set; }
21+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace Optimizely.TestContainers.Models;
1+
namespace Optimizely.TestContainers.Models.Pages;
22

33
[ContentType(
44
GUID = "7B873919-11AC-4DF4-B9E8-09F414F76164",

src/Web/Models/Pages/StartPage.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System.ComponentModel.DataAnnotations;
2+
3+
namespace Optimizely.TestContainers.Models.Pages;
4+
//using AlloyTemplates.Models.Blocks;
5+
6+
/// <summary>
7+
/// Used for the site's start page and also acts as a container for site settings
8+
/// </summary>
9+
[ContentType(
10+
GUID = "19671657-B684-4D95-A61F-8DD4FE60D559"
11+
/*GroupName = Global.GroupNames.Specialized*/)]
12+
//[SiteImageUrl]
13+
/*
14+
[AvailableContentTypes(
15+
Availability.Specific,
16+
Include = new[] { typeof(ContainerPage), typeof(ProductPage), typeof(StandardPage), typeof(ISearchPage), typeof(LandingPage), typeof(ContentFolder) }, // Pages we can create under the start page...
17+
ExcludeOn = new[] { typeof(ContainerPage), typeof(ProductPage), typeof(StandardPage), typeof(ISearchPage), typeof(LandingPage) })] // ...and underneath those we can't create additional start pages
18+
*/
19+
public class StartPage : PageData
20+
{
21+
[Display(
22+
GroupName = SystemTabNames.Content,
23+
Order = 320)]
24+
[CultureSpecific]
25+
public virtual ContentArea MainContentArea { get; set; }
26+
27+
/*
28+
[Display(GroupName = Global.GroupNames.SiteSettings, Order = 300)]
29+
public virtual LinkItemCollection ProductPageLinks { get; set; }
30+
31+
[Display(GroupName = Global.GroupNames.SiteSettings, Order = 350)]
32+
public virtual LinkItemCollection CompanyInformationPageLinks { get; set; }
33+
34+
[Display(GroupName = Global.GroupNames.SiteSettings, Order = 400)]
35+
public virtual LinkItemCollection NewsPageLinks { get; set; }
36+
37+
[Display(GroupName = Global.GroupNames.SiteSettings, Order = 450)]
38+
public virtual LinkItemCollection CustomerZonePageLinks { get; set; }
39+
40+
[Display(GroupName = Global.GroupNames.SiteSettings)]
41+
public virtual PageReference GlobalNewsPageLink { get; set; }
42+
43+
[Display(GroupName = Global.GroupNames.SiteSettings)]
44+
public virtual PageReference ContactsPageLink { get; set; }
45+
46+
[Display(GroupName = Global.GroupNames.SiteSettings)]
47+
public virtual PageReference SearchPageLink { get; set; }
48+
49+
[Display(GroupName = Global.GroupNames.SiteSettings)]
50+
public virtual SiteLogotypeBlock SiteLogotype { get; set; }
51+
*/
52+
}
Binary file not shown.
Lines changed: 95 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,130 @@
1-
using EPiServer;
1+
using System.Reflection;
2+
using EPiServer;
3+
using EPiServer.Cms.Shell;
4+
using Microsoft.Extensions.Hosting;
5+
using Microsoft.Extensions.DependencyInjection;
6+
using EPiServer.Framework.Initialization;
27
using EPiServer.Core;
8+
using EPiServer.Data;
39
using EPiServer.DataAccess;
10+
using EPiServer.Framework;
11+
using EPiServer.Framework.Web;
412
using EPiServer.Security;
5-
using Microsoft.Extensions.DependencyInjection;
13+
using EPiServer.Web;
14+
using EPiServer.Web.Templating;
15+
using Microsoft.AspNetCore.Hosting;
616
using Optimizely.TestContainers;
717
using Optimizely.TestContainers.Models;
18+
using Optimizely.TestContainers.Models.Pages;
19+
using OptimizelyTestContainers.Tests;
820
using Testcontainers.MsSql;
921

10-
namespace OptimizelyTestContainers.Tests;
11-
12-
public class NewsPageIntegrationTests : IAsyncLifetime
22+
public class NewsPageIntegrationTest : IAsyncLifetime
1323
{
14-
private readonly MsSqlContainer _dbContainer;
15-
private readonly IServiceProvider _serviceProvider;
16-
private readonly IContentRepository _contentRepository;
17-
private ContentReference _startPageRef;
24+
private IHost _host;
25+
private IServiceProvider _services;
26+
private MsSqlContainer _dbContainer;
1827

19-
public NewsPageIntegrationTests()
28+
public async Task InitializeAsync()
2029
{
30+
// Start SQL Server container
2131
_dbContainer = new MsSqlBuilder()
2232
.WithImage("mcr.microsoft.com/mssql/server:2022-latest")
2333
.WithPassword("yourStrong(!)Password")
2434
.Build();
25-
26-
// Simulated Optimizely CMS service setup
27-
var services = new ServiceCollection();
28-
29-
// Register CMS core services for testing (simplified)
30-
services
31-
.AddCmsHost() // AddCms?
32-
.AddEmbeddedLocalization<Startup>();
33-
34-
_serviceProvider = services.BuildServiceProvider();
35-
_contentRepository = _serviceProvider.GetRequiredService<IContentRepository>();
36-
}
3735

38-
public async Task InitializeAsync()
39-
{
4036
await _dbContainer.StartAsync();
37+
38+
// Build CMS host
39+
_host = Host.CreateDefaultBuilder()
40+
.ConfigureCmsDefaults()
41+
.ConfigureWebHostDefaults(webBuilder =>
42+
{
43+
webBuilder.ConfigureServices((context, services) =>
44+
{
45+
services.AddCms();
46+
services.AddCmsHost();
47+
services.AddCmsFrameworkWeb();
48+
49+
services.AddCmsCoreWeb(); // Adds core CMS services
50+
services.AddCmsTemplating();
51+
services.AddCmsUI();
52+
53+
services.Configure<DataAccessOptions>(opt =>
54+
{
55+
var cs = _dbContainer.GetConnectionString();
56+
57+
opt.SetConnectionString(cs);
58+
});
59+
60+
services.AddTransient<OptimizelyDataImporter>();
61+
});
62+
63+
webBuilder.UseStartup<Startup>();
64+
})
65+
.Build();
66+
67+
4168

42-
// Add mock SiteDefinition etc. as needed...
4369

44-
// Create a dummy start page
45-
var root = ContentReference.StartPage;
46-
var startPage = _contentRepository.GetDefault<PageData>(root);
47-
startPage.Name = "Start";
48-
_startPageRef = _contentRepository.Save(startPage, SaveAction.Publish, AccessLevel.NoAccess);
70+
await _host.StartAsync();
71+
72+
// Run initialization engine (simulate application startup)
73+
var initializer = _host.Services.GetRequiredService<InitializationEngine>();
74+
if (initializer.InitializationState != InitializationState.Initialized)
75+
initializer.Initialize();
76+
77+
_services = _host.Services;
4978
}
5079

5180
public async Task DisposeAsync()
5281
{
82+
await _host.StopAsync();
5383
await _dbContainer.DisposeAsync();
5484
}
5585

5686
[Fact]
5787
public void Can_Create_And_Read_NewsPage()
5888
{
5989
// Arrange
60-
var newsPage = _contentRepository.GetDefault<NewsPage>(_startPageRef);
61-
newsPage.Name = "Breaking News";
62-
newsPage.Title = "Aliens Invade Earth";
90+
var repo = _services.GetRequiredService<IContentRepository>();
91+
92+
// Import test data
93+
var basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!;
94+
var episerverDataFile = Path.Combine(basePath, "DefaultSiteContent.episerverdata");
95+
96+
var dataImporter = _services.GetRequiredService<OptimizelyDataImporter>();
97+
dataImporter.Import(episerverDataFile);
98+
99+
100+
// Find StartPage from root
101+
// Setup site definition
102+
103+
var startPage = repo.GetChildren<StartPage>(ContentReference.RootPage).First();
104+
105+
var siteDefinitionRepo = _services.GetRequiredService<ISiteDefinitionRepository>();
106+
107+
siteDefinitionRepo.Save(new SiteDefinition()
108+
{
109+
Name = "TestSite",
110+
StartPage = startPage.ContentLink,
111+
SiteUrl = new Uri("http://localhost"),
112+
});
113+
114+
var allSites = siteDefinitionRepo.List();
115+
116+
var site = allSites.First();
117+
118+
var news = repo.GetDefault<NewsPage>(site.StartPage);
119+
news.Name = "Alien Invasion";
120+
news.Title = "Martians Landed in Stockholm";
63121

64122
// Act
65-
var savedRef = _contentRepository.Save(newsPage, SaveAction.Publish, AccessLevel.NoAccess);
66-
var loaded = _contentRepository.Get<NewsPage>(savedRef);
123+
var savedRef = repo.Save(news, SaveAction.Publish, AccessLevel.NoAccess);
124+
var loaded = repo.Get<NewsPage>(savedRef);
67125

68126
// Assert
69127
Assert.NotNull(loaded);
70-
Assert.Equal("Aliens Invade Earth", loaded.Title);
128+
Assert.Equal("Martians Landed in Stockholm", loaded.Title);
71129
}
72-
}
130+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using Castle.DynamicProxy.Generators.Emitters;
2+
using EPiServer.Core;
3+
using EPiServer.Core.Transfer;
4+
using EPiServer.Enterprise;
5+
using Microsoft.Extensions.Logging;
6+
7+
namespace OptimizelyTestContainers.Tests;
8+
9+
public class OptimizelyDataImporter(ILogger<OptimizelyDataImporter> logger, IDataImporter dataImporter, IContentEvents contentEvents)
10+
{
11+
public void Import(string importFilePath)
12+
{
13+
contentEvents.PublishedContent += (s, e) =>
14+
{
15+
logger.LogInformation("Published: {ContentName}", e.Content.Name);
16+
};
17+
18+
using var stream = File.OpenRead(importFilePath);
19+
20+
var options = new ImportOptions
21+
{
22+
KeepIdentity = true,
23+
EnsureContentNameUniqueness = false,
24+
ValidateDestination = true,
25+
//ValidateContent = true,
26+
//ImportFiles = true,
27+
TransferType = TypeOfTransfer.Importing,
28+
AutoCloseStream = true,
29+
};
30+
31+
var importLog = dataImporter.Import(stream, ContentReference.RootPage, options);
32+
33+
var errors = importLog.Errors.ToList();
34+
var warnings = importLog.Warnings.ToList();
35+
36+
// TODO: Throw on error(s) and log warnings
37+
}
38+
}

test/OptimizelyTestContainers.Tests/OptimizelyTestContainers.Tests.csproj

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net9.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<IsPackable>false</IsPackable>
@@ -24,4 +24,10 @@
2424
<ProjectReference Include="..\..\src\Web\Optimizely.TestContainers.csproj" />
2525
</ItemGroup>
2626

27+
<ItemGroup>
28+
<None Update="DefaultSiteContent.episerverdata">
29+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
30+
</None>
31+
</ItemGroup>
32+
2733
</Project>

0 commit comments

Comments
 (0)