using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using w4c_workflows.Controllers; using w4c_workflows.Data; using w4c_workflows.Services.Quota; using Xunit; namespace w4c_workflows.Tests; /// /// P1-14: resetting a tenant's monthly execution counter is a platform-admin /// action. A tenant must not be able to zero its own quota, and the gate must /// fail closed when Workflows:AdminApiKey is not configured at all. /// [Collection("WorkflowsPostgres")] public class WorkflowQuotaControllerTests { private readonly WorkflowsPostgresFixture _fixture; public WorkflowQuotaControllerTests(WorkflowsPostgresFixture fixture) => _fixture = fixture; private static string Tenant() => "q" + Guid.NewGuid().ToString("N")[..12]; private static IConfiguration Config(string? adminKey) => new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { ["Workflows:AdminApiKey"] = adminKey, }) .Build(); private static WorkflowQuotaController Controller( WorkflowQuotaService quota, string tenantId, string? adminKey, string? providedKey) { var http = new DefaultHttpContext(); http.Items["TenantId"] = tenantId; if (providedKey != null) http.Request.Headers["X-Admin-Key"] = providedKey; return new WorkflowQuotaController(quota, Config(adminKey)) { ControllerContext = new ControllerContext { HttpContext = http }, }; } [Fact] public async Task Reset_is_forbidden_when_no_admin_key_is_configured() { var tenantId = Tenant(); await using var db = _fixture.CreateContext(); var result = await Controller( QuotaTestData.Service(db), tenantId, adminKey: null, providedKey: "anything").Reset(default); var forbidden = Assert.IsType(result); Assert.Equal(StatusCodes.Status403Forbidden, forbidden.StatusCode); } [Fact] public async Task Reset_is_forbidden_with_the_wrong_admin_key() { var tenantId = Tenant(); await using var db = _fixture.CreateContext(); var result = await Controller( QuotaTestData.Service(db), tenantId, adminKey: "correct-secret", providedKey: "wrong-secret") .Reset(default); var forbidden = Assert.IsType(result); Assert.Equal(StatusCodes.Status403Forbidden, forbidden.StatusCode); } [Fact] public async Task Reset_with_the_admin_key_zeroes_the_counter() { var tenantId = Tenant(); await using var db = _fixture.CreateContext(); var quota = QuotaTestData.Service(db, new WorkflowQuotaOptions { RunsPerMonth = 10 }); Assert.True(await quota.TryReserveAsync(tenantId)); Assert.Equal(1, (await quota.GetAsync(tenantId)).Used); var controller = Controller(quota, tenantId, adminKey: "correct-secret", providedKey: "correct-secret"); var result = Assert.IsType(await controller.Reset(default)); var snapshot = Assert.IsType(result.Value); Assert.Equal(0, snapshot.Used); Assert.Equal(0, (await quota.GetAsync(tenantId)).Used); } }