From e39055dd1238043ddabeb04cdc7ec5a8f3bf4221 Mon Sep 17 00:00:00 2001 From: Doug Waldron Date: Thu, 23 Apr 2026 11:53:15 -0400 Subject: [PATCH 1/3] Use async overloads in unit test teardown methods --- tests/Notifications.API.Tests/AddNotificationTests.cs | 6 +++--- .../Notifications.API.Tests/DeactivateNotificationTests.cs | 6 +++--- tests/Notifications.API.Tests/GetNotificationsTests.cs | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/Notifications.API.Tests/AddNotificationTests.cs b/tests/Notifications.API.Tests/AddNotificationTests.cs index 2e73f65..cd1bba7 100644 --- a/tests/Notifications.API.Tests/AddNotificationTests.cs +++ b/tests/Notifications.API.Tests/AddNotificationTests.cs @@ -22,10 +22,10 @@ public async Task Setup() } [TearDown] - public void TearDown() + public async Task TearDown() { - _dbContext.Database.EnsureDeleted(); - _dbContext.Dispose(); + await _dbContext.Database.EnsureDeletedAsync(); + await _dbContext.DisposeAsync(); } [Test] diff --git a/tests/Notifications.API.Tests/DeactivateNotificationTests.cs b/tests/Notifications.API.Tests/DeactivateNotificationTests.cs index 9a17908..86de249 100644 --- a/tests/Notifications.API.Tests/DeactivateNotificationTests.cs +++ b/tests/Notifications.API.Tests/DeactivateNotificationTests.cs @@ -23,10 +23,10 @@ public async Task Setup() } [TearDown] - public void TearDown() + public async Task TearDown() { - _dbContext.Database.EnsureDeleted(); - _dbContext.Dispose(); + await _dbContext.Database.EnsureDeletedAsync(); + await _dbContext.DisposeAsync(); } [Test] diff --git a/tests/Notifications.API.Tests/GetNotificationsTests.cs b/tests/Notifications.API.Tests/GetNotificationsTests.cs index 7ba6431..01143c0 100644 --- a/tests/Notifications.API.Tests/GetNotificationsTests.cs +++ b/tests/Notifications.API.Tests/GetNotificationsTests.cs @@ -21,10 +21,10 @@ public async Task Setup() } [TearDown] - public void TearDown() + public async Task TearDown() { - _dbContext.Database.EnsureDeleted(); - _dbContext.Dispose(); + await _dbContext.Database.EnsureDeletedAsync(); + await _dbContext.DisposeAsync(); } [Test] From 7699de5005c4cf0b525e12b484abd2dbff2d63df Mon Sep 17 00:00:00 2001 From: Doug Waldron Date: Thu, 23 Apr 2026 11:55:32 -0400 Subject: [PATCH 2/3] Await all EF DB calls --- src/Notifications.API/Database/Repository.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Notifications.API/Database/Repository.cs b/src/Notifications.API/Database/Repository.cs index b3e9533..7b68dbb 100644 --- a/src/Notifications.API/Database/Repository.cs +++ b/src/Notifications.API/Database/Repository.cs @@ -7,18 +7,18 @@ internal static class Repository { // Read - public static Task> GetCurrentNotificationsAsync(AppDbContext db) => - db.Notifications + public static async Task> GetCurrentNotificationsAsync(AppDbContext db) => + await db.Notifications .Where(n => n.Active && n.DisplayStart < DateTime.Now && DateTime.Now < n.DisplayEnd) .OrderBy(n => n.DisplayStart).ThenBy(n => n.DisplayEnd).ToListAsync(); - public static Task> GetFutureNotificationsAsync(AppDbContext db) => - db.Notifications + public static async Task> GetFutureNotificationsAsync(AppDbContext db) => + await db.Notifications .Where(n => n.Active && DateTime.Now < n.DisplayStart) .OrderBy(n => n.DisplayStart).ThenBy(n => n.DisplayEnd).ToListAsync(); - public static Task> GetAllNotifications(AppDbContext db) => - db.Notifications + public static async Task> GetAllNotifications(AppDbContext db) => + await db.Notifications .OrderBy(n => n.DisplayStart).ThenBy(n => n.DisplayEnd).ToListAsync(); // Write From cd26ad60ddc6e883d2a4e173bc00da8c2c7f9610 Mon Sep 17 00:00:00 2001 From: Doug Waldron Date: Thu, 23 Apr 2026 11:56:26 -0400 Subject: [PATCH 3/3] Add DB check to health API endpoint --- src/Notifications.API/Database/Repository.cs | 4 ++ src/Notifications.API/Platform/Endpoints.cs | 3 +- src/Notifications.API/Program.cs | 2 +- .../REST-Samples/successes.http | 4 ++ .../HealthCheckTests.cs | 39 +++++++++++++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 tests/Notifications.API.Tests/HealthCheckTests.cs diff --git a/src/Notifications.API/Database/Repository.cs b/src/Notifications.API/Database/Repository.cs index 7b68dbb..d7f13b7 100644 --- a/src/Notifications.API/Database/Repository.cs +++ b/src/Notifications.API/Database/Repository.cs @@ -6,6 +6,10 @@ namespace Notifications.Database; internal static class Repository { // Read + public static async Task DbAvailable(AppDbContext db) => + await db.Database.CanConnectAsync() + ? TypedResults.Ok("OK") + : TypedResults.InternalServerError("Database not available."); public static async Task> GetCurrentNotificationsAsync(AppDbContext db) => await db.Notifications diff --git a/src/Notifications.API/Platform/Endpoints.cs b/src/Notifications.API/Platform/Endpoints.cs index 9763074..94bdd7c 100644 --- a/src/Notifications.API/Platform/Endpoints.cs +++ b/src/Notifications.API/Platform/Endpoints.cs @@ -7,7 +7,8 @@ internal static class Endpoints public static void MapEndpoints(this IEndpointRouteBuilder app) { // Status endpoints - app.MapGet("/health", () => Results.Ok("OK")); + app.MapGet("/", () => Results.Ok()); + app.MapGet("/health", Repository.DbAvailable); app.MapGet("/version", () => Results.Ok(new { AppSettings.Version })); // Public endpoints diff --git a/src/Notifications.API/Program.cs b/src/Notifications.API/Program.cs index 4e8ac50..21206ae 100644 --- a/src/Notifications.API/Program.cs +++ b/src/Notifications.API/Program.cs @@ -19,6 +19,6 @@ var app = builder.Build(); app.UseRaygun(); app.MapEndpoints(); -await app.BuildDatabaseAsync(); +await app.BuildDatabaseAsync(); await app.RunAsync(); diff --git a/src/Notifications.API/REST-Samples/successes.http b/src/Notifications.API/REST-Samples/successes.http index b4e3820..3e797e8 100644 --- a/src/Notifications.API/REST-Samples/successes.http +++ b/src/Notifications.API/REST-Samples/successes.http @@ -5,6 +5,10 @@ @ApiKey = client-api-key-1 @ApiKey2 = client-api-key-2 +### Connect to API +GET {{HostAddress}} +Accept: application/json + ### Check health. GET {{HostAddress}}/health Accept: application/json diff --git a/tests/Notifications.API.Tests/HealthCheckTests.cs b/tests/Notifications.API.Tests/HealthCheckTests.cs new file mode 100644 index 0000000..5e4d798 --- /dev/null +++ b/tests/Notifications.API.Tests/HealthCheckTests.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.Http.HttpResults; +using Microsoft.EntityFrameworkCore; +using Notifications.Database; + +namespace Notifications.API.Tests; + +[TestFixture] +public class HealthCheckTests +{ + private AppDbContext _dbContext; + + [SetUp] + public async Task Setup() + { + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "RepositoryTest") + .Options; + + _dbContext = new AppDbContext(options); + await _dbContext.Database.EnsureCreatedAsync(); + } + + [TearDown] + public async Task TearDown() + { + await _dbContext.Database.EnsureDeletedAsync(); + await _dbContext.DisposeAsync(); + } + + [Test] + public async Task DbAvailable_IfAvailable() + { + // Act + var results = await Repository.DbAvailable(_dbContext); + + // Assert + results.Should().BeOfType>(); + } +}