using System.Net; using System.Net.Http.Json; using PnvPanel.IntegrationTests.TestSupport; using Xunit; using static PnvPanel.IntegrationTests.TestSupport.AuthTestHelper; namespace PnvPanel.IntegrationTests.Billing; [Collection(IntegrationTestCollection.Name)] public class BillingFlowTests(PnvPanelWebApplicationFactory factory) { private sealed record RoleResponse(Guid Id, string Name, bool BillingEnabled); private sealed record ActivationRequestResponse(Guid Id); private sealed record BillingStatusResponse( bool BillingEnabled, DateTimeOffset? PaidUntil, bool Suspended, string RequisitesText, object? ActiveRequest ); /// /// Проверяет сквозной путь, недоступный unit-тестам (RoleService — Infrastructure/Identity): /// назначение billing-роли автоматически выдаёт грейс-период, и он виден пользователю через /// /api/billing/status. /// [Fact] public async Task AssigningBillingRole_GrantsGracePeriod_VisibleInBillingStatus() { using var adminClient = factory.CreateClient(); var adminToken = await LoginAsAdminAsync(adminClient); adminClient.UseBearerToken(adminToken); var createRoleResponse = await adminClient.PostJsonAsync( "/api/admin/roles", new { name = $"billing_{Guid.NewGuid():N}"[..20], maxConfigs = 5, maxIpLimit = -1, billingEnabled = true, } ); Assert.Equal(HttpStatusCode.OK, createRoleResponse.StatusCode); var role = await createRoleResponse.ReadAsAsync(); Assert.True(role!.BillingEnabled); using var userClient = factory.CreateClient(); var userName = $"bill_{Guid.NewGuid():N}"[..20]; var (userId, userToken) = await RegisterAndLoginAsync(userClient, userName, "P@ssw0rd123"); userClient.UseBearerToken(userToken); var activationRequestResponse = await userClient.PostJsonAsync( "/api/activation/request", new { comment = (string?)null } ); var activationRequest = await activationRequestResponse.ReadAsAsync(); var approveActivationResponse = await adminClient.PostAsync( $"/api/admin/activation-requests/{activationRequest!.Id}/approve", content: null ); Assert.Equal(HttpStatusCode.NoContent, approveActivationResponse.StatusCode); var assignRoleResponse = await adminClient.PatchAsJsonAsync( $"/api/admin/users/{userId}/role", new { roleId = role.Id }, PnvPanel.IntegrationTests.TestSupport.HttpClientJsonExtensions.JsonOptions ); Assert.Equal(HttpStatusCode.NoContent, assignRoleResponse.StatusCode); var beforeCheck = DateTimeOffset.UtcNow; var statusResponse = await userClient.GetAsync("/api/billing/status"); Assert.Equal(HttpStatusCode.OK, statusResponse.StatusCode); var status = await statusResponse.ReadAsAsync(); Assert.True(status!.BillingEnabled); Assert.False(status.Suspended); Assert.NotNull(status.PaidUntil); // Дефолтный грейс — 7 дней (BillingSettings.DefaultGraceDays), пока админ не настроил своё. Assert.True(status.PaidUntil > beforeCheck.AddDays(6)); Assert.True(status.PaidUntil < beforeCheck.AddDays(8)); } }