Skip to content

Commit 75b9ccc

Browse files
More work in progress
1 parent 4f548ad commit 75b9ccc

17 files changed

+1252
-139
lines changed

src/Optimizely.TestContainers.Commerce.Tests/CommerceCatalogIntegrationTests.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,10 @@
1313

1414
namespace Optimizely.TestContainers.Commerce.Tests;
1515

16-
/// <summary>
17-
/// Integration tests for Commerce catalog functionality (catalogs, nodes, products).
18-
/// Tests Commerce-specific content types and operations.
19-
/// </summary>
20-
[Collection("CommerceCatalogIntegrationTests")]
2116
public class CommerceCatalogIntegrationTests() : OptimizelyIntegrationTestBase(includeCommerce: true)
2217
{
23-
/// <summary>
24-
/// Configure web host with Commerce-specific Startup and services.
25-
/// The base class provides CMS, Commerce, and Find configuration automatically.
26-
/// </summary>
2718
protected override void ConfigureWebHostBuilder(IWebHostBuilder webHostBuilder)
2819
{
29-
// Register the Startup class that configures Commerce services and content types
3020
webHostBuilder.UseStartup<Startup>();
3121
}
3222

src/Optimizely.TestContainers.Commerce.Tests/CommerceCatalogNegativeTests.cs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.ComponentModel.DataAnnotations;
21
using System.Globalization;
32
using EPiServer;
43
using EPiServer.Commerce.Catalog.ContentTypes;
@@ -14,20 +13,10 @@
1413

1514
namespace Optimizely.TestContainers.Commerce.Tests;
1615

17-
/// <summary>
18-
/// Negative/edge case integration tests for Commerce catalog functionality.
19-
/// Tests error handling, validation, and edge cases for Commerce operations.
20-
/// </summary>
21-
[Collection("CommerceCatalogNegativeTests")]
2216
public class CommerceCatalogNegativeTests() : OptimizelyIntegrationTestBase(includeCommerce: true)
2317
{
24-
/// <summary>
25-
/// Configure web host with Commerce-specific Startup and services.
26-
/// The base class provides CMS, Commerce, and Find configuration automatically.
27-
/// </summary>
2818
protected override void ConfigureWebHostBuilder(IWebHostBuilder webHostBuilder)
2919
{
30-
// Register the Startup class that configures Commerce services and content types
3120
webHostBuilder.UseStartup<Startup>();
3221
}
3322

@@ -74,7 +63,7 @@ public void Cannot_Save_Catalog_Without_Name()
7463
catalog.LengthBase = "cm";
7564

7665
// Act & Assert
77-
Assert.Throws<ValidationException>(() => contentRepository.Save(catalog, SaveAction.Publish, AccessLevel.NoAccess));
66+
Assert.Throws<EPiServerException>(() => contentRepository.Save(catalog, SaveAction.Publish, AccessLevel.NoAccess));
7867
}
7968

8069
[Fact]
@@ -253,4 +242,4 @@ public void Can_Create_Multiple_Products_In_Same_Node()
253242
Assert.Equal("Product 2", loaded2.Name);
254243
Assert.NotEqual(loaded1.ContentLink, loaded2.ContentLink);
255244
}
256-
}
245+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
using System.ComponentModel.DataAnnotations;
2+
using EPiServer.Commerce.Catalog.ContentTypes;
3+
using EPiServer.Commerce.Catalog.DataAnnotations;
4+
using EPiServer.Core;
5+
using EPiServer.DataAbstraction;
6+
using EPiServer.DataAnnotations;
7+
using Optimizely.TestContainers.Commerce.Tests.Models.Commerce;
8+
9+
namespace Optimizely.TestContainers.Commerce.Tests.Models.Commerce;
10+
11+
public class TestProductTests
12+
{
13+
[Fact]
14+
public void TestProduct_Should_Have_CatalogContentType_Attribute()
15+
{
16+
// Arrange & Act
17+
var attribute = typeof(TestProduct).GetCustomAttributes(typeof(CatalogContentTypeAttribute), false)
18+
.FirstOrDefault() as CatalogContentTypeAttribute;
19+
20+
// Assert
21+
Assert.NotNull(attribute);
22+
Assert.Equal("0B06DE9B-6AE3-40FB-909E-E718CCC260AE", attribute.GUID);
23+
Assert.Equal("Test Product", attribute.DisplayName);
24+
Assert.Equal("Test product for integration tests.", attribute.Description);
25+
}
26+
27+
[Fact]
28+
public void TestProduct_Should_Inherit_From_ProductContent()
29+
{
30+
// Arrange & Act
31+
var isProductContent = typeof(ProductContent).IsAssignableFrom(typeof(TestProduct));
32+
33+
// Assert
34+
Assert.True(isProductContent);
35+
}
36+
37+
[Fact]
38+
public void Description_Property_Should_Be_Virtual()
39+
{
40+
// Arrange
41+
var property = typeof(TestProduct).GetProperty(nameof(TestProduct.Description));
42+
43+
// Act & Assert
44+
Assert.NotNull(property);
45+
Assert.True(property.GetMethod?.IsVirtual);
46+
}
47+
48+
[Fact]
49+
public void Description_Property_Should_Have_Display_Attribute()
50+
{
51+
// Arrange
52+
var property = typeof(TestProduct).GetProperty(nameof(TestProduct.Description));
53+
54+
// Act
55+
var displayAttribute = property?.GetCustomAttributes(typeof(DisplayAttribute), false)
56+
.FirstOrDefault() as DisplayAttribute;
57+
58+
// Assert
59+
Assert.NotNull(displayAttribute);
60+
Assert.Equal("Description", displayAttribute.Name);
61+
Assert.Equal(SystemTabNames.Content, displayAttribute.GroupName);
62+
Assert.Equal(1, displayAttribute.Order);
63+
}
64+
65+
[Fact]
66+
public void Description_Property_Should_Have_Searchable_Attribute()
67+
{
68+
// Arrange
69+
var property = typeof(TestProduct).GetProperty(nameof(TestProduct.Description));
70+
71+
// Act
72+
var attribute = property?.GetCustomAttributes(typeof(SearchableAttribute), false)
73+
.FirstOrDefault();
74+
75+
// Assert
76+
Assert.NotNull(attribute);
77+
}
78+
79+
[Fact]
80+
public void Description_Property_Should_Have_CultureSpecific_Attribute()
81+
{
82+
// Arrange
83+
var property = typeof(TestProduct).GetProperty(nameof(TestProduct.Description));
84+
85+
// Act
86+
var attribute = property?.GetCustomAttributes(typeof(CultureSpecificAttribute), false)
87+
.FirstOrDefault();
88+
89+
// Assert
90+
Assert.NotNull(attribute);
91+
}
92+
93+
[Fact]
94+
public void Description_Property_Should_Have_Tokenize_Attribute()
95+
{
96+
// Arrange
97+
var property = typeof(TestProduct).GetProperty(nameof(TestProduct.Description));
98+
99+
// Act
100+
var attribute = property?.GetCustomAttributes(typeof(TokenizeAttribute), false)
101+
.FirstOrDefault();
102+
103+
// Assert
104+
Assert.NotNull(attribute);
105+
}
106+
107+
[Fact]
108+
public void Description_Property_Should_Have_IncludeInDefaultSearch_Attribute()
109+
{
110+
// Arrange
111+
var property = typeof(TestProduct).GetProperty(nameof(TestProduct.Description));
112+
113+
// Act
114+
var attribute = property?.GetCustomAttributes(typeof(IncludeInDefaultSearchAttribute), false)
115+
.FirstOrDefault();
116+
117+
// Assert
118+
Assert.NotNull(attribute);
119+
}
120+
121+
[Fact]
122+
public void TestProduct_Can_Be_Instantiated()
123+
{
124+
// Act
125+
var testProduct = new TestProduct();
126+
127+
// Assert
128+
Assert.NotNull(testProduct);
129+
}
130+
131+
[Fact]
132+
public void Description_Property_Can_Be_Set_And_Retrieved()
133+
{
134+
// Arrange
135+
var testProduct = new TestProduct();
136+
var expectedDescription = new XhtmlString("<p>Test product description</p>");
137+
138+
// Act
139+
testProduct.Description = expectedDescription;
140+
141+
// Assert
142+
Assert.Equal(expectedDescription, testProduct.Description);
143+
}
144+
}

src/Optimizely.TestContainers.Commerce.Tests/Startup.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@
55
using Microsoft.AspNetCore.Builder;
66
using Microsoft.AspNetCore.Hosting;
77
using Microsoft.Extensions.DependencyInjection;
8+
using Microsoft.Extensions.Hosting;
89

910
namespace Optimizely.TestContainers.Commerce.Tests;
1011

1112
public class Startup(IWebHostEnvironment webHostingEnvironment)
1213
{
1314
public void ConfigureServices(IServiceCollection services)
1415
{
15-
AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(webHostingEnvironment.ContentRootPath, "App_Data"));
16-
17-
services.Configure<SchedulerOptions>(options => options.Enabled = false);
16+
if (webHostingEnvironment.IsDevelopment())
17+
{
18+
AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(webHostingEnvironment.ContentRootPath, "App_Data"));
1819

19-
services.AddHttpContextAccessor();
20+
services.Configure<SchedulerOptions>(options => options.Enabled = false);
21+
}
2022

2123
services
2224
.AddCmsAspNetIdentity<ApplicationUser>()
@@ -28,6 +30,11 @@ public void ConfigureServices(IServiceCollection services)
2830

2931
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
3032
{
33+
if (env.IsDevelopment())
34+
{
35+
app.UseDeveloperExceptionPage();
36+
}
37+
3138
app.UseStaticFiles();
3239
app.UseRouting();
3340
app.UseAuthentication();

src/Optimizely.TestContainers.Commerce.Tests/StartupTests.cs

Lines changed: 7 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
using EPiServer;
1+
using EPiServer.Commerce.Catalog;
2+
using EPiServer.Core;
23
using EPiServer.Scheduler;
3-
using Mediachase.Commerce.Catalog;
44
using Microsoft.AspNetCore.Builder;
55
using Microsoft.AspNetCore.Hosting;
66
using Microsoft.AspNetCore.Http;
@@ -18,16 +18,6 @@ public void ConfigureServices_Should_Add_CMS_And_Commerce_Services()
1818
{
1919
// Arrange
2020
var services = new ServiceCollection();
21-
services.AddLogging();
22-
services.AddOptions();
23-
services.AddRouting();
24-
services.AddHttpContextAccessor();
25-
// Register IHttpContextFactory - required by EPiServer framework
26-
var mockHttpContextFactory = new Mock<IHttpContextFactory>();
27-
services.AddSingleton(mockHttpContextFactory.Object);
28-
services.AddCms(); // Add CMS services
29-
services.AddCommerce(); // Add Commerce services
30-
3121
var mockEnvironment = new Mock<IWebHostEnvironment>();
3222
mockEnvironment.Setup(x => x.EnvironmentName).Returns(Environments.Production);
3323
mockEnvironment.Setup(x => x.ContentRootPath).Returns(Path.GetTempPath());
@@ -50,16 +40,6 @@ public void ConfigureServices_In_Development_Should_Configure_Scheduler_Options(
5040
{
5141
// Arrange
5242
var services = new ServiceCollection();
53-
services.AddLogging();
54-
services.AddOptions();
55-
services.AddRouting();
56-
services.AddHttpContextAccessor();
57-
// Register IHttpContextFactory - required by EPiServer framework
58-
var mockHttpContextFactory = new Mock<IHttpContextFactory>();
59-
services.AddSingleton(mockHttpContextFactory.Object);
60-
services.AddCms(); // Add CMS services
61-
services.AddCommerce(); // Add Commerce services
62-
6343
var mockEnvironment = new Mock<IWebHostEnvironment>();
6444
mockEnvironment.Setup(x => x.EnvironmentName).Returns(Environments.Development);
6545
mockEnvironment.Setup(x => x.ContentRootPath).Returns(Path.GetTempPath());
@@ -81,16 +61,6 @@ public void ConfigureServices_In_Production_Should_Not_Configure_Scheduler_Optio
8161
{
8262
// Arrange
8363
var services = new ServiceCollection();
84-
services.AddLogging();
85-
services.AddOptions();
86-
services.AddRouting();
87-
services.AddHttpContextAccessor();
88-
// Register IHttpContextFactory - required by EPiServer framework
89-
var mockHttpContextFactory = new Mock<IHttpContextFactory>();
90-
services.AddSingleton(mockHttpContextFactory.Object);
91-
services.AddCms(); // Add CMS services
92-
services.AddCommerce(); // Add Commerce services
93-
9464
var mockEnvironment = new Mock<IWebHostEnvironment>();
9565
mockEnvironment.Setup(x => x.EnvironmentName).Returns(Environments.Production);
9666
mockEnvironment.Setup(x => x.ContentRootPath).Returns(Path.GetTempPath());
@@ -107,7 +77,7 @@ public void ConfigureServices_In_Production_Should_Not_Configure_Scheduler_Optio
10777
Assert.NotNull(schedulerOptions);
10878
}
10979

110-
[Fact(Skip = "Mock setup incomplete - IApplicationBuilder requires additional configuration for middleware pipeline testing")]
80+
[Fact]
11181
public void Configure_Should_Setup_Middleware_Pipeline()
11282
{
11383
// Arrange
@@ -118,15 +88,10 @@ public void Configure_Should_Setup_Middleware_Pipeline()
11888

11989
var startup = new Startup(mockEnvironment.Object);
12090

121-
// Setup application services with routing
122-
var services = new ServiceCollection();
123-
services.AddRouting();
124-
var serviceProvider = services.BuildServiceProvider();
125-
12691
mockAppBuilder.Setup(x => x.Use(It.IsAny<Func<RequestDelegate, RequestDelegate>>()))
12792
.Returns(mockAppBuilder.Object);
12893
mockAppBuilder.Setup(x => x.New()).Returns(mockAppBuilder.Object);
129-
mockAppBuilder.Setup(x => x.ApplicationServices).Returns(serviceProvider);
94+
mockAppBuilder.Setup(x => x.ApplicationServices).Returns(new ServiceCollection().BuildServiceProvider());
13095

13196
// Act
13297
startup.Configure(mockAppBuilder.Object, mockEnvironment.Object);
@@ -135,7 +100,7 @@ public void Configure_Should_Setup_Middleware_Pipeline()
135100
mockAppBuilder.Verify(x => x.Use(It.IsAny<Func<RequestDelegate, RequestDelegate>>()), Times.AtLeastOnce);
136101
}
137102

138-
[Fact(Skip = "Mock setup incomplete - IApplicationBuilder requires additional configuration for developer exception page testing")]
103+
[Fact]
139104
public void Configure_In_Development_Should_Use_DeveloperExceptionPage()
140105
{
141106
// Arrange
@@ -146,15 +111,10 @@ public void Configure_In_Development_Should_Use_DeveloperExceptionPage()
146111

147112
var startup = new Startup(mockEnvironment.Object);
148113

149-
// Setup application services with routing
150-
var services = new ServiceCollection();
151-
services.AddRouting();
152-
var serviceProvider = services.BuildServiceProvider();
153-
154114
mockAppBuilder.Setup(x => x.Use(It.IsAny<Func<RequestDelegate, RequestDelegate>>()))
155115
.Returns(mockAppBuilder.Object);
156116
mockAppBuilder.Setup(x => x.New()).Returns(mockAppBuilder.Object);
157-
mockAppBuilder.Setup(x => x.ApplicationServices).Returns(serviceProvider);
117+
mockAppBuilder.Setup(x => x.ApplicationServices).Returns(new ServiceCollection().BuildServiceProvider());
158118

159119
// Act
160120
startup.Configure(mockAppBuilder.Object, mockEnvironment.Object);
@@ -177,4 +137,4 @@ public void Startup_Constructor_Should_Accept_WebHostEnvironment()
177137
// Assert
178138
Assert.NotNull(startup);
179139
}
180-
}
140+
}

0 commit comments

Comments
 (0)