Files
Elternbeirat/Elternbeirat.Web.Tests/RouteSmokeTests.cs
T

87 lines
2.8 KiB
C#

using System.Net;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
namespace Elternbeirat.Web.Tests;
/// <summary>
/// Smoke tests: every known route must return 200, unknown routes must return
/// 404. This catches broken content files, renamed slugs or routing regressions
/// before a deploy.
/// <para>
/// The post routes now read from PocketBase, so the tests point the web app at the
/// seeded container from <see cref="PocketBaseFixture"/> (shared via the
/// collection) and assert against its known slugs. Requires Docker, like the
/// client tests.
/// </para>
/// </summary>
[Collection(PocketBaseTestGroup.Name)]
public sealed class RouteSmokeTests : IDisposable
{
// WithWebHostBuilder returns a new factory that wraps the base one; both are
// disposable, so both are held and disposed to avoid leaking either.
private readonly WebApplicationFactory<Program> _baseFactory = new();
private readonly WebApplicationFactory<Program> _factory;
public RouteSmokeTests(PocketBaseFixture pocketBase)
{
// Point the app's PocketBaseClient at the seeded test container instead of
// the value from appsettings. UseSetting (not ConfigureAppConfiguration)
// because it wins over appsettings.Development.json, which otherwise pins the
// client to localhost:8090 while the test container uses a random port.
_factory = _baseFactory.WithWebHostBuilder(builder =>
builder.UseSetting("PocketBase:BaseUrl", pocketBase.BaseUrl.ToString()));
}
public void Dispose()
{
_factory.Dispose();
_baseFactory.Dispose();
}
/// <summary>
/// Every route that a visitor can reach through the navigation, the FAQ hub
/// or the news section. The post slugs match the fixture's seed.
/// </summary>
public static TheoryData<string> KnownRoutes =>
[
"/",
"/board",
"/patrons",
"/faq",
"/faq-mensa",
"/downloads",
"/contact",
"/imprint",
"/privacy",
"/posts",
"/posts/new-board",
"/posts/new-hall",
"/events",
"/events.ics",
];
[Theory]
[MemberData(nameof(KnownRoutes))]
public async Task Known_route_returns_200(string route)
{
var client = _factory.CreateClient();
var response = await client.GetAsync(new Uri(route, UriKind.Relative));
response.StatusCode.ShouldBe(HttpStatusCode.OK);
}
[Theory]
[InlineData("/gibt-es-nicht")]
[InlineData("/posts/gibt-es-nicht")]
public async Task Unknown_route_returns_404(string route)
{
var client = _factory.CreateClient();
var response = await client.GetAsync(new Uri(route, UriKind.Relative));
response.StatusCode.ShouldBe(HttpStatusCode.NotFound);
}
}