diff --git a/.github/workflows/dotnet-core-pull-request.yml b/.github/workflows/dotnet-core-pull-request.yml
index b1c8251..1261010 100644
--- a/.github/workflows/dotnet-core-pull-request.yml
+++ b/.github/workflows/dotnet-core-pull-request.yml
@@ -13,11 +13,10 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --no-restore --verbosity normal
-
diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml
index 0c1ee1a..700cbe4 100644
--- a/.github/workflows/dotnet-core.yml
+++ b/.github/workflows/dotnet-core.yml
@@ -1,4 +1,4 @@
-name: .NET 6 & 7
+name: .NET 6, 7 & 8
on:
push:
@@ -13,7 +13,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Install dependencies
run: dotnet restore
- name: Build
@@ -23,11 +23,10 @@ jobs:
- name: Build solution and generate NuGet package
run: |
cd src\DotNetEd.CoreAdmin
- dotnet pack -c Release -o out
+ dotnet pack -c Release -o out
- name: Setup nuget
uses: nuget/setup-nuget@v1
with:
nuget-api-key: ${{ secrets.NUGET_API_KEY }}
- name: Push generated package to Nuget
run: nuget push src\DotNetEd.CoreAdmin\out\*.nupkg -SkipDuplicate -NoSymbols -Source https://api.nuget.org/v3/index.json
-
diff --git a/src/DotNetEd.CoreAdmin.DemoAppDotNet6/DotNetEd.CoreAdmin.DemoAppDotNet6.csproj b/src/DotNetEd.CoreAdmin.DemoAppDotNet6/DotNetEd.CoreAdmin.DemoAppDotNet6.csproj
index bbc1d29..8425f4b 100644
--- a/src/DotNetEd.CoreAdmin.DemoAppDotNet6/DotNetEd.CoreAdmin.DemoAppDotNet6.csproj
+++ b/src/DotNetEd.CoreAdmin.DemoAppDotNet6/DotNetEd.CoreAdmin.DemoAppDotNet6.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net6.0;net7.0;net8.0
enable
enable
@@ -18,12 +18,14 @@
-
-
-
+
+
+
-
+
+
+
diff --git a/src/DotNetEd.CoreAdmin/DotNetEd.CoreAdmin.csproj b/src/DotNetEd.CoreAdmin/DotNetEd.CoreAdmin.csproj
index c8c8056..ce07753 100644
--- a/src/DotNetEd.CoreAdmin/DotNetEd.CoreAdmin.csproj
+++ b/src/DotNetEd.CoreAdmin/DotNetEd.CoreAdmin.csproj
@@ -1,19 +1,20 @@
- net6.0;net7.0
+ net6.0;net7.0;net8.0
true
false
false
CoreAdmin
2.7.1
- Automagically add an Admin Panel to your .NET 6 or .NET 7 web app.
+ Automagically add an Admin Panel to your .NET 6, .NET 7 or .NET 8 web app.
Core Admin Panel for ASP.NET Core
edandersen
- Copyright ©2022 Ed Andersen
+ Copyright © 2022 Ed Andersen
https://github.com/edandersen/core-admin
LGPL-3.0-or-later
disable
+ true
@@ -46,7 +47,8 @@
-
+
+
diff --git a/tests/DotNetEd.CoreAdmin.IntegrationTestApp/DotNetEd.CoreAdmin.IntegrationTestApp.csproj b/tests/DotNetEd.CoreAdmin.IntegrationTestApp/DotNetEd.CoreAdmin.IntegrationTestApp.csproj
index ec6d0fa..29263c1 100644
--- a/tests/DotNetEd.CoreAdmin.IntegrationTestApp/DotNetEd.CoreAdmin.IntegrationTestApp.csproj
+++ b/tests/DotNetEd.CoreAdmin.IntegrationTestApp/DotNetEd.CoreAdmin.IntegrationTestApp.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net7.0;net8.0
disable
diff --git a/tests/DotNetEd.CoreAdmin.IntegrationTestApp/IntegrationTestStartup.cs b/tests/DotNetEd.CoreAdmin.IntegrationTestApp/IntegrationTestStartup.cs
deleted file mode 100644
index 333ce05..0000000
--- a/tests/DotNetEd.CoreAdmin.IntegrationTestApp/IntegrationTestStartup.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using DotNetEd.CoreAdmin;
-using Microsoft.Extensions.Hosting;
-using DotNetEd.CoreAdmin.Controllers;
-using Microsoft.AspNetCore.Mvc.Authorization;
-using DotNetEd.CoreAdmin.IntegrationTestApp.Middleware;
-
-namespace DotNetEd.CoreAdmin.IntegrationTests.TestApp
-{
- public class IntegrationTestStartup
- {
- public IntegrationTestStartup(IConfiguration configuration)
- {
- Configuration = configuration;
- }
-
- public IConfiguration Configuration { get; }
-
- // This method gets called by the runtime. Use this method to add services to the container.
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddControllersWithViews().AddApplicationPart(typeof(CoreAdminDataController).Assembly); ;
- }
-
- // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- app.UseMiddleware();
-
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- else
- {
- app.UseExceptionHandler("/Home/Error");
- // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
- app.UseHsts();
- }
- app.UseHttpsRedirection();
- // app.UseStaticFiles();
-
- app.UseRouting();
-
- app.UseAuthorization();
-
- app.UseEndpoints(endpoints =>
- {
- endpoints.MapControllerRoute(
- name: "default",
- pattern: "{controller=Home}/{action=Index}/{id?}");
- });
- }
- }
-}
diff --git a/tests/DotNetEd.CoreAdmin.IntegrationTestApp/Program.cs b/tests/DotNetEd.CoreAdmin.IntegrationTestApp/Program.cs
index 479efe0..92c1d50 100644
--- a/tests/DotNetEd.CoreAdmin.IntegrationTestApp/Program.cs
+++ b/tests/DotNetEd.CoreAdmin.IntegrationTestApp/Program.cs
@@ -1,27 +1,47 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using DotNetEd.CoreAdmin.IntegrationTests.TestApp;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.Configuration;
+using DotNetEd.CoreAdmin.Controllers;
+using DotNetEd.CoreAdmin.IntegrationTestApp.Middleware;
+
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-namespace DotNetEd.CoreAdmin.IntegrationTestApp
+
+
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddControllersWithViews().AddApplicationPart(typeof(CoreAdminDataController).Assembly);
+
+
+var app = builder.Build();
+
+app.UseMiddleware();
+
+if (app.Environment.IsDevelopment())
+{
+ app.UseDeveloperExceptionPage();
+}
+else
{
- public class Program
- {
- public static void Main(string[] args)
- {
- CreateHostBuilder(args).Build().Run();
- }
-
- public static IHostBuilder CreateHostBuilder(string[] args) =>
- Host.CreateDefaultBuilder(args)
- .ConfigureWebHostDefaults(webBuilder =>
- {
- webBuilder.UseStartup();
- });
- }
+ app.UseExceptionHandler("/Home/Error");
+ // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+ app.UseHsts();
}
+app.UseHttpsRedirection();
+// app.UseStaticFiles();
+
+app.UseRouting();
+
+app.UseAuthorization();
+
+app.UseEndpoints(endpoints =>
+{
+ endpoints.MapControllerRoute(
+ name: "default",
+ pattern: "{controller=Home}/{action=Index}/{id?}");
+});
+
+app.Run();
+
+
+
+public partial class Program { }
diff --git a/tests/DotNetEd.CoreAdmin.IntegrationTests/BasicTests.cs b/tests/DotNetEd.CoreAdmin.IntegrationTests/BasicTests.cs
index f7c3a5c..8032158 100644
--- a/tests/DotNetEd.CoreAdmin.IntegrationTests/BasicTests.cs
+++ b/tests/DotNetEd.CoreAdmin.IntegrationTests/BasicTests.cs
@@ -1,20 +1,23 @@
-using DotNetEd.CoreAdmin.IntegrationTests.TestApp;
+using System;
+using System.Threading.Tasks;
+
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Threading.Tasks;
using Xunit;
+using DotNetEd.CoreAdmin.IntegrationTests.TestApp;
+
+
namespace DotNetEd.CoreAdmin.IntegrationTests
{
- public class BasicTests : IClassFixture>
+ public class BasicTests : IClassFixture
{
- private readonly IntegrationTestsWebHostFactory _factory;
+ private readonly TestAppFixture _fixture;
- public BasicTests(IntegrationTestsWebHostFactory factory)
+ public BasicTests(TestAppFixture fixture)
{
- _factory = factory;
+ _fixture = fixture;
}
static void ConfigureTestServices(IServiceCollection services) { }
@@ -23,7 +26,7 @@ static void ConfigureTestServices(IServiceCollection services) { }
public async Task ShowsTestEntitiesOnScreenOnAdminScreen()
{
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServices);
}).CreateClient();
@@ -45,21 +48,26 @@ public async Task ShowsTestEntitiesOnScreenOnAdminScreen()
[Fact]
public async Task ShowDataInDbSetOnScreen()
{
- var dbContext = _factory.Services.GetService();
- var idGuid = Guid.NewGuid();
- var nameGuidString = Guid.NewGuid().ToString();
- dbContext.TestEntities.Add(new TestApp.Entities.TestEntity() { Id = idGuid, Name = nameGuidString});
- await dbContext.SaveChangesAsync();
-
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServices);
}).CreateClient();
+ var idGuid = Guid.NewGuid();
+ var nameGuidString = Guid.NewGuid().ToString();
+
+ using (var scope = _fixture.Factory.Services.CreateScope())
+ {
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+ dbContext.TestEntities.Add(new TestApp.Entities.TestEntity() { Id = idGuid, Name = nameGuidString });
+ await dbContext.SaveChangesAsync();
+ }
+
// Act
var response = await client.GetAsync("/coreadmindata/index/testentities");
+ // Assert
response.EnsureSuccessStatusCode(); // Status Code 200-299
Assert.Equal("text/html; charset=utf-8",
response.Content.Headers.ContentType.ToString());
diff --git a/tests/DotNetEd.CoreAdmin.IntegrationTests/CrudTests.cs b/tests/DotNetEd.CoreAdmin.IntegrationTests/CrudTests.cs
index 01666b4..9903213 100644
--- a/tests/DotNetEd.CoreAdmin.IntegrationTests/CrudTests.cs
+++ b/tests/DotNetEd.CoreAdmin.IntegrationTests/CrudTests.cs
@@ -3,22 +3,25 @@
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
-using DotNetEd.CoreAdmin.IntegrationTests.TestApp;
+
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
+using DotNetEd.CoreAdmin.IntegrationTests.TestApp;
+
+
namespace DotNetEd.CoreAdmin.IntegrationTests
{
- public class CrudTests : IClassFixture>
+ public class CrudTests : IClassFixture
{
- private readonly IntegrationTestsWebHostFactory _factory;
+ private readonly TestAppFixture _fixture;
- public CrudTests(IntegrationTestsWebHostFactory factory)
+ public CrudTests(TestAppFixture fixture)
{
- _factory = factory;
+ _fixture = fixture;
}
static void ConfigureTestServices(IServiceCollection services) { }
@@ -26,168 +29,209 @@ static void ConfigureTestServices(IServiceCollection services) { }
[Fact]
public async Task DeleteHappyPath()
{
- var dbContext = _factory.Services.GetService();
- var idGuid = Guid.NewGuid();
- var nameGuidString = Guid.NewGuid().ToString();
- dbContext.TestEntities.Add(new TestApp.Entities.TestEntity() { Id = idGuid, Name = nameGuidString});
- await dbContext.SaveChangesAsync();
-
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServices);
}).CreateClient();
+ var idGuid = Guid.NewGuid();
+ var nameGuidString = Guid.NewGuid().ToString();
+
+ using (var scope = _fixture.Factory.Services.CreateScope())
+ {
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+ dbContext.TestEntities.Add(new TestApp.Entities.TestEntity() { Id = idGuid, Name = nameGuidString });
+ await dbContext.SaveChangesAsync();
+ }
+
+ // Act
// Do the post to delete the item
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"));
var data = new Dictionary() { { "id", idGuid.ToString() }, { "dbSetName", "testentities" } };
var response = await client.PostAsync("/coreadmindata/DeleteEntityPost", new FormUrlEncodedContent(data));
+
+ // Assert
response.EnsureSuccessStatusCode();
// check to see if the item is deleted from DB context
- Assert.False(await dbContext.TestEntities.AnyAsync(test => test.Id == idGuid));
-
+ using (var scope = _fixture.Factory.Services.CreateScope())
+ {
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+ Assert.False(await dbContext.TestEntities.AnyAsync(test => test.Id == idGuid));
+ }
}
[Fact]
public async Task CreateHappyPath()
{
- var dbContext = _factory.Services.GetService();
- var idGuid = Guid.NewGuid();
- var nameGuidString = Guid.NewGuid().ToString();
-
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServices);
}).CreateClient();
+ var nameGuidString = Guid.NewGuid().ToString();
+
+ // Act
// Do the post to delete the item
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"));
var data = new Dictionary() { { "Name", nameGuidString }, { "Id", nameGuidString } };
var response = await client.PostAsync("/coreadmindata/CreateEntityPost/testentities?dbSetName=testentities", new FormUrlEncodedContent(data));
- response.EnsureSuccessStatusCode();
-
- Assert.True(await dbContext.TestEntities.AnyAsync(test => test.Name == nameGuidString));
+ // Assert
+ response.EnsureSuccessStatusCode();
+ using (var scope = _fixture.Factory.Services.CreateScope())
+ {
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+ Assert.True(await dbContext.TestEntities.AnyAsync(test => test.Name == nameGuidString));
+ }
}
[Fact]
public async Task Create_ChildEntityWithNonNullableFK_HappyPath()
{
- var dbContext = _factory.Services.GetService();
- var idGuid = Guid.NewGuid();
- var nameGuidString = Guid.NewGuid().ToString();
-
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServices);
}).CreateClient();
+
+ var idGuid = Guid.NewGuid();
+ var nameGuidString = Guid.NewGuid().ToString();
+
+ // Act
// Do the post to create the child item
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"));
var data = new Dictionary() { { "Name", nameGuidString }, { "Id", nameGuidString } };
var response = await client.PostAsync("/coreadmindata/CreateEntityPost/testchildentities?dbSetName=testchildentities", new FormUrlEncodedContent(data));
+
+ // Assert
response.EnsureSuccessStatusCode();
- Assert.True(await dbContext.TestChildEntities.AnyAsync(test => test.Name == nameGuidString));
+ using (var scope = _fixture.Factory.Services.CreateScope())
+ {
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+ Assert.True(await dbContext.TestChildEntities.AnyAsync(test => test.Name == nameGuidString));
+ }
var parentId = Guid.NewGuid();
data = new Dictionary() { { "ParentId", parentId.ToString() }, { "ChildId", idGuid.ToString() }, { "dbSetName", "testparententities" } };
response = await client.PostAsync("/coreadmindata/CreateEntityPost/testparententities", new FormUrlEncodedContent(data));
-
- response.EnsureSuccessStatusCode();
- Assert.True(await dbContext.TestParentEntities.AnyAsync(test => test.ChildId == idGuid));
+ response.EnsureSuccessStatusCode();
+ using (var scope = _fixture.Factory.Services.CreateScope())
+ {
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+ Assert.True(await dbContext.TestParentEntities.AnyAsync(test => test.ChildId == idGuid));
+ }
}
[Fact]
public async Task CreateTestEntityWithValidationError_TooLongName()
{
- var dbContext = _factory.Services.GetService();
- var idGuid = Guid.NewGuid();
- var nameString = new string('*', 5000); // Name should have MaxLength(100)
-
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServices);
}).CreateClient();
+
+ var idGuid = Guid.NewGuid();
+ var nameString = new string('*', 5000); // Name should have MaxLength(100)
+
+ // Act
// Do the post to delete the item
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"));
var data = new Dictionary() { { "Name", nameString }, { "Id", idGuid.ToString() } };
var response = await client.PostAsync("/coreadmindata/CreateEntityPost/testentities?dbSetName=testentities", new FormUrlEncodedContent(data));
+
+ // Assert
response.EnsureSuccessStatusCode();
// make sure it has not written to DB
- Assert.False(await dbContext.TestEntities.AnyAsync(test => test.Name == nameString));
-
+ using (var scope = _fixture.Factory.Services.CreateScope())
+ {
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+ Assert.False(await dbContext.TestEntities.AnyAsync(test => test.Name == nameString));
+ }
}
[Fact]
public async Task CreateHappyPath_WithAutogeneratedKey()
{
- var dbContext = _factory.Services.GetService();
- // var idGuid = Guid.NewGuid();
- var nameGuidString = Guid.NewGuid().ToString();
-
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServices);
}).CreateClient();
+ var nameGuidString = Guid.NewGuid().ToString();
+
+ // Act
// Do the post to delete the item
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"));
var data = new Dictionary() { { "Name", nameGuidString } };
var response = await client.PostAsync("/coreadmindata/CreateEntityPost/TestAutogeneratedKeyEntities?dbSetName=TestAutogeneratedKeyEntities", new FormUrlEncodedContent(data));
- response.EnsureSuccessStatusCode();
+ // Assert
+ response.EnsureSuccessStatusCode();
- Assert.True(await dbContext.TestAutogeneratedKeyEntities.AnyAsync(test => test.Name == nameGuidString));
-
+ using (var scope = _fixture.Factory.Services.CreateScope())
+ {
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+ Assert.True(await dbContext.TestAutogeneratedKeyEntities.AnyAsync(test => test.Name == nameGuidString));
+ }
}
[Fact]
public async Task UpdateHappyPath()
{
- var dbContext = _factory.Services.GetService();
- var idGuid = Guid.NewGuid();
- var nameGuidString = Guid.NewGuid().ToString();
- dbContext.TestEntities.Add(new TestApp.Entities.TestEntity() { Id = idGuid, Name = nameGuidString});
- await dbContext.SaveChangesAsync();
-
- var updatedNameGuid = Guid.NewGuid().ToString();
-
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServices);
}).CreateClient();
+ var idGuid = Guid.NewGuid();
+ var nameGuidString = Guid.NewGuid().ToString();
+ var updatedNameGuid = Guid.NewGuid().ToString();
+
+ using (var scope = _fixture.Factory.Services.CreateScope())
+ {
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+ dbContext.TestEntities.Add(new TestApp.Entities.TestEntity() { Id = idGuid, Name = nameGuidString});
+ await dbContext.SaveChangesAsync();
+ }
+
+ // Act
// Do the post to update the item
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"));
var data = new Dictionary() { { "Name", updatedNameGuid }, { "Id", idGuid.ToString() } };
var response = await client.PostAsync("/coreadmindata/editentityPost/" + idGuid.ToString() + "?dbSetName=TestEntities", new FormUrlEncodedContent(data));
+
+ // Assert
response.EnsureSuccessStatusCode();
// check to see if the item is updated from DB context
- var foundEntity = dbContext.TestEntities.First(e => e.Id == idGuid);
- dbContext.Entry(foundEntity).Reload();
- Assert.True(dbContext.TestEntities.First(e => e.Id == idGuid).Name == updatedNameGuid);
-
+ using (var scope = _fixture.Factory.Services.CreateScope())
+ {
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+ var foundEntity = dbContext.TestEntities.First(e => e.Id == idGuid);
+ dbContext.Entry(foundEntity).Reload();
+ Assert.True(dbContext.TestEntities.First(e => e.Id == idGuid).Name == updatedNameGuid);
+ }
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/DotNetEd.CoreAdmin.IntegrationTests/DotNetEd.CoreAdmin.IntegrationTests.csproj b/tests/DotNetEd.CoreAdmin.IntegrationTests/DotNetEd.CoreAdmin.IntegrationTests.csproj
index fa3cb29..c8d3af7 100644
--- a/tests/DotNetEd.CoreAdmin.IntegrationTests/DotNetEd.CoreAdmin.IntegrationTests.csproj
+++ b/tests/DotNetEd.CoreAdmin.IntegrationTests/DotNetEd.CoreAdmin.IntegrationTests.csproj
@@ -1,27 +1,37 @@
- net6.0
+ net6.0;net7.0;net8.0
annotations
false
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
-
+
+
+
+
+
+
+
diff --git a/tests/DotNetEd.CoreAdmin.IntegrationTests/IntegrationTestsWebHostFactory.cs b/tests/DotNetEd.CoreAdmin.IntegrationTests/IntegrationTestsWebHostFactory.cs
index 47204b9..b383c1b 100644
--- a/tests/DotNetEd.CoreAdmin.IntegrationTests/IntegrationTestsWebHostFactory.cs
+++ b/tests/DotNetEd.CoreAdmin.IntegrationTests/IntegrationTestsWebHostFactory.cs
@@ -1,74 +1,26 @@
using DotNetEd.CoreAdmin.IntegrationTests.TestApp;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Hosting;
-using Microsoft.AspNetCore.TestHost;
-using Microsoft.AspNetCore.Mvc.Authorization;
+
namespace DotNetEd.CoreAdmin.IntegrationTests
{
- public class IntegrationTestsWebHostFactory
- : WebApplicationFactory where TStartup : class
+ public class IntegrationTestsWebHostFactory : WebApplicationFactory
{
- protected override IHostBuilder CreateHostBuilder()
- {
- var builder = Host.CreateDefaultBuilder()
- .ConfigureWebHostDefaults(x =>
- {
- // x.UseEnvironment("Development");
- x.UseStartup().UseTestServer();
- });
- return builder;
- }
-
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
- {
+ {
// Add ApplicationDbContext using an in-memory database for testing.
services.AddDbContext(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
});
- // Build the service provider.
- var sp = services.BuildServiceProvider();
-
- // Create a scope to obtain a reference to the database
- // context (ApplicationDbContext).
- using (var scope = sp.CreateScope())
- {
- var scopedServices = scope.ServiceProvider;
- var db = scopedServices.GetRequiredService();
- var logger = scopedServices
- .GetRequiredService>>();
-
- // Ensure the database is created.
- db.Database.EnsureCreated();
-
- try
- {
- // Seed the database with test data.
- // Utilities.InitializeDbForTests(db);
- }
- catch (Exception ex)
- {
- logger.LogError(ex, "An error occurred seeding the " +
- "database with test messages. Error: {Message}", ex.Message);
- }
- }
-
services.AddCoreAdmin();
});
-
-
}
}
}
diff --git a/tests/DotNetEd.CoreAdmin.IntegrationTests/OptionsTests.cs b/tests/DotNetEd.CoreAdmin.IntegrationTests/OptionsTests.cs
index 0ad18b3..e8c6828 100644
--- a/tests/DotNetEd.CoreAdmin.IntegrationTests/OptionsTests.cs
+++ b/tests/DotNetEd.CoreAdmin.IntegrationTests/OptionsTests.cs
@@ -1,23 +1,25 @@
-using DotNetEd.CoreAdmin.IntegrationTests.TestApp;
-using DotNetEd.CoreAdmin.IntegrationTests.TestApp.Entities;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
using Xunit;
+using DotNetEd.CoreAdmin.IntegrationTests.TestApp.Entities;
+
+
namespace DotNetEd.CoreAdmin.IntegrationTests
{
- public class OptionsTests : IClassFixture>
+ public class OptionsTests : IClassFixture
{
- private readonly IntegrationTestsWebHostFactory _factory;
+ private readonly TestAppFixture _fixture;
- public OptionsTests(IntegrationTestsWebHostFactory factory)
+ public OptionsTests(TestAppFixture fixture)
{
- _factory = factory;
+ _fixture = fixture;
}
static void ConfigureTestServices(IServiceCollection services) { }
@@ -26,7 +28,7 @@ static void ConfigureTestServices(IServiceCollection services) { }
public async Task ReturnsBuiltInAssetPathWhenCdnOptionsNotSet()
{
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServices);
}).CreateClient();
@@ -51,7 +53,7 @@ static void ConfigureTestServicesWithOptionsIgnoringDbSets(IServiceCollection se
[Fact] public async Task IgnoreEntityTypes_DoesNotIncludeIgnoredDbSets()
{
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(services =>
ConfigureTestServicesWithOptionsIgnoringDbSets(services,
@@ -72,7 +74,7 @@ public async Task ReturnsCdnAssetPathWhenCdnOptionsSet()
var cdnPath = "https://wow-an-amazing-cdn.com/assets";
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServices);
builder.Configure(
diff --git a/tests/DotNetEd.CoreAdmin.IntegrationTests/SecurityTests.cs b/tests/DotNetEd.CoreAdmin.IntegrationTests/SecurityTests.cs
index ebabe76..09b4ee7 100644
--- a/tests/DotNetEd.CoreAdmin.IntegrationTests/SecurityTests.cs
+++ b/tests/DotNetEd.CoreAdmin.IntegrationTests/SecurityTests.cs
@@ -1,27 +1,28 @@
-using DotNetEd.CoreAdmin.IntegrationTests.TestApp;
+using System;
+using System.Threading.Tasks;
+
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Threading.Tasks;
using Xunit;
+
namespace DotNetEd.CoreAdmin.IntegrationTests
{
- public class SecurityTests : IClassFixture>
+ public class SecurityTests : IClassFixture
{
- private readonly IntegrationTestsWebHostFactory _factory;
+ private readonly TestAppFixture _fixture;
- public SecurityTests(IntegrationTestsWebHostFactory factory)
+ public SecurityTests(TestAppFixture fixture)
{
- _factory = factory;
+ _fixture = fixture;
}
static void ConfigureTestServices(IServiceCollection services) { }
- static void ConfigureTestServicesWithSecurity(IServiceCollection services) {
- services.AddCoreAdmin("TestRole");
+ static void ConfigureTestServicesWithSecurity(IServiceCollection services) {
+ services.AddCoreAdmin("TestRole");
}
[Obsolete]
@@ -39,7 +40,7 @@ static void ConfigureTestServicesWithSecurityAndAlternativeTestRole(IServiceColl
public async Task ShowsWarningMessageInDevelopmentModeWhenNoSecuritySet()
{
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServices); }).CreateClient();
@@ -61,7 +62,7 @@ public async Task ShowsWarningMessageInDevelopmentModeWhenNoSecuritySet()
public async Task DoesNotShowWarningMessageInDevelopmentModeWhenSecurityIsSet()
{
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServicesWithSecurity);
}).CreateClient();
@@ -84,7 +85,7 @@ public async Task DoesNotShowWarningMessageInDevelopmentModeWhenSecurityIsSet()
public async Task ReturnsUnauthorisedInDevelopmentModeWhenSecurityIsSetAndCheckFails()
{
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Development");
builder.ConfigureTestServices(ConfigureTestServicesWithSecurityAndAlternativeTestRole);
}).CreateClient();
@@ -100,8 +101,11 @@ public async Task ReturnsUnauthorisedInDevelopmentModeWhenSecurityIsSetAndCheckF
public async Task ReturnsUnauthorizedWhenInProductionButNoSecuritySet()
{
// Arrange
- var client = _factory.WithWebHostBuilder(builder =>
- builder.ConfigureTestServices(ConfigureTestServices)).CreateClient();
+ var client = _fixture.Factory.WithWebHostBuilder(builder =>
+ {
+ builder.ConfigureTestServices(ConfigureTestServices);
+ builder.UseEnvironment("Production");
+ }).CreateClient();
// Act
var response = await client.GetAsync("/coreadmin");
@@ -114,7 +118,7 @@ public async Task ReturnsUnauthorizedWhenInProductionButNoSecuritySet()
public async Task SuccessStatusCodeAndUsesRoleWhenInProductionAndRoleCheckSet()
{
// Arrange
- var client = _factory.WithWebHostBuilder(builder =>
+ var client = _fixture.Factory.WithWebHostBuilder(builder =>
builder.ConfigureTestServices(ConfigureTestServicesWithSecurity)).CreateClient();
// Act
@@ -134,8 +138,8 @@ public async Task SuccessStatusCodeAndCallsCustomAuthMethodInProductionAndAuthMe
var authMethod = new Func>(() => { authCalled = true; return Task.FromResult(true); });
// Arrange
- var client = _factory.WithWebHostBuilder(builder =>
- builder.ConfigureTestServices(services =>
+ var client = _fixture.Factory.WithWebHostBuilder(builder =>
+ builder.ConfigureTestServices(services =>
ConfigureTestServicesWithSecurityAuthMethod(services, authMethod))).CreateClient();
// Act
@@ -155,7 +159,7 @@ public async Task ReturnsUnauthorizedWhenInProductionCustomAuthMethodFails()
var authMethod = new Func>(() => { authCalled = true; return Task.FromResult(false); });
// Arrange
- var client = _factory.WithWebHostBuilder(builder =>
+ var client = _fixture.Factory.WithWebHostBuilder(builder =>
builder.ConfigureTestServices(services =>
ConfigureTestServicesWithSecurityAuthMethod(services, authMethod))).CreateClient();
@@ -175,7 +179,7 @@ public async Task ReturnsUnauthorizedWhenInProductionNewCustomAuthMethodFails()
var authMethod = new Func>((serviceProvider) => { authCalled = true; return Task.FromResult(false); });
// Arrange
- var client = _factory.WithWebHostBuilder(builder => {
+ var client = _fixture.Factory.WithWebHostBuilder(builder => {
builder.UseEnvironment("Production");
builder.ConfigureTestServices(ConfigureTestServices);
builder.Configure(
diff --git a/tests/DotNetEd.CoreAdmin.IntegrationTests/TestAppFixture.cs b/tests/DotNetEd.CoreAdmin.IntegrationTests/TestAppFixture.cs
new file mode 100644
index 0000000..c4219e2
--- /dev/null
+++ b/tests/DotNetEd.CoreAdmin.IntegrationTests/TestAppFixture.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Threading.Tasks;
+
+using DotNetEd.CoreAdmin.IntegrationTests.TestApp;
+
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+using Xunit;
+
+
+namespace DotNetEd.CoreAdmin.IntegrationTests;
+
+public sealed class TestAppFixture : IAsyncLifetime
+{
+ public IntegrationTestsWebHostFactory Factory { get; } = new();
+
+ public Task InitializeAsync()
+ {
+ // Create a scope to obtain a reference to the database
+ // context (ApplicationDbContext).
+ using (var scope = Factory.Services.CreateScope())
+ {
+ var scopedServices = scope.ServiceProvider;
+ var db = scopedServices.GetRequiredService();
+ var logger = scopedServices
+ .GetRequiredService>();
+
+ // Ensure the database is created.
+ db.Database.EnsureCreated();
+
+ try
+ {
+ // Seed the database with test data.
+ // Utilities.InitializeDbForTests(db);
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, "An error occurred seeding the " +
+ "database with test messages. Error: {Message}", ex.Message);
+ }
+ }
+
+ return Task.CompletedTask;
+ }
+
+ public async Task DisposeAsync()
+ {
+ await Factory.DisposeAsync();
+ }
+}