d03ca01172
CI / backend (pull_request) Successful in 52s
CI / frontend (pull_request) Successful in 23s
CI / format (pull_request) Successful in 51s
CI / db-tests (pull_request) Successful in 52s
Security / secrets (pull_request) Successful in 4s
Security / dependencies (pull_request) Successful in 1m1s
.NET 8 security support ends 2026-11-10; .NET 10 is LTS to Nov 2028. - TargetFramework net8.0 -> net10.0 (Directory.Build.props) - EF Core 8.0.4 -> 10.0.9; Npgsql provider 8.0.4 -> 10.0.2; Pgvector.EFCore 0.2.0 -> 0.3.0; ASP.NET/Extensions packages -> 10.0.9 - Dockerfile sdk/aspnet 8.0 -> 10.0; CI setup-dotnet -> 10.0.x - Modernised deprecated APIs: X509CertificateLoader (SYSLIB0057), KnownIPNetworks + System.Net.IPNetwork.Parse (ASPDEPR005) - Adapted tests to Npgsql 10's eager connection-string validation (dummy conn string in test factories; behaviour change from lazy 8.x) Verified: 0 errors/0 warnings; all 54 tests green on net10; the 3 LiveDb tests green against a real pgvector container on the new EF10/Npgsql10/Pgvector 0.3 stack; dotnet format clean; vulnerable-package scan clean; the .NET 10 API Docker image builds successfully. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
61 lines
2.6 KiB
C#
61 lines
2.6 KiB
C#
using System.Net;
|
|
using FluentAssertions;
|
|
using Microsoft.AspNetCore.Mvc.Testing;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Xunit;
|
|
|
|
namespace InboxIntel.IntegrationTests;
|
|
|
|
/// <summary>
|
|
/// Test host that disables startup auto-migration so the factory boots without
|
|
/// a live PostgreSQL instance. The auth tests below never touch the database
|
|
/// (the challenge happens in middleware before any controller runs).
|
|
/// </summary>
|
|
public class TestAppFactory : WebApplicationFactory<Program>
|
|
{
|
|
protected override IHost CreateHost(IHostBuilder builder)
|
|
{
|
|
builder.ConfigureHostConfiguration(cfg => cfg.AddInMemoryCollection(new Dictionary<string, string?>
|
|
{
|
|
["Database:AutoMigrate"] = "false",
|
|
// Npgsql 10 eagerly validates the connection string when the DbContext is
|
|
// resolved (8.x was lazy); these tests never connect, but the string must parse.
|
|
["ConnectionStrings:Postgres"] = "Host=localhost;Database=test;Username=test;Password=test",
|
|
// Dummy OAuth creds so the Google challenge produces a real 302 redirect
|
|
// (an empty ClientId can make the handler throw instead of redirecting).
|
|
["GoogleOAuth:ClientId"] = "test-client-id",
|
|
["GoogleOAuth:ClientSecret"] = "test-client-secret"
|
|
}));
|
|
return base.CreateHost(builder);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Smoke tests proving the host boots and authorization is enforced. A fuller
|
|
/// suite would swap PostgreSQL for a Testcontainers instance and the Gmail
|
|
/// client for a fake, then exercise sync -> analytics end to end.
|
|
/// </summary>
|
|
public class AuthEndpointsTests : IClassFixture<TestAppFactory>
|
|
{
|
|
private readonly TestAppFactory _factory;
|
|
public AuthEndpointsTests(TestAppFactory factory) => _factory = factory;
|
|
|
|
[Fact]
|
|
public async Task Protected_endpoint_challenges_when_anonymous()
|
|
{
|
|
var client = _factory.CreateClient(new WebApplicationFactoryClientOptions { AllowAutoRedirect = false });
|
|
var resp = await client.GetAsync("/api/v1/analytics/dashboard");
|
|
// Unauthenticated -> redirect to Google challenge (302) or 401.
|
|
resp.StatusCode.Should().BeOneOf(HttpStatusCode.Found, HttpStatusCode.Unauthorized);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Login_endpoint_is_anonymous()
|
|
{
|
|
var client = _factory.CreateClient(new WebApplicationFactoryClientOptions { AllowAutoRedirect = false });
|
|
var resp = await client.GetAsync("/api/v1/auth/login");
|
|
resp.StatusCode.Should().Be(HttpStatusCode.Redirect); // 302 to Google
|
|
}
|
|
}
|