using System.Net; using System.Net.Http.Headers; using FluentAssertions; using foodmarket.IntegrationTests.Support; using Xunit; namespace foodmarket.IntegrationTests; /// Sprint 13: Hangfire Dashboard защищён SuperAdminHangfireFilter. /// /// ВАЖНО: в тестовом окружении ApiFactory выставляет /// Hangfire__Enabled=false (иначе Hangfire-сервер плодил бы свои /// таблицы в одноразовом контейнере). Когда сервер выключен, /// app.UseHangfireDashboard не вызывается → /hangfire отдаёт 404. /// /// Поэтому в этих тестах мы проверяем «дашборд НЕ открыт без авторизации»: /// допустимый результат — 401, 403 или 404 (любая форма «нет доступа»). /// SuperAdmin-кейс не проверяем здесь: для него на stage есть e2e-проверка /// (см. stage-smoke). Это компромисс ради не-зависимости теста от /// Hangfire-сервера. [Collection(ApiCollection.Name)] public class HangfireAccessTests { private readonly ApiFactory _factory; public HangfireAccessTests(ApiFactory factory) => _factory = factory; [Fact] public async Task Anonymous_hangfire_returns_unauthorized() { using var client = _factory.CreateClient(); var resp = await client.GetAsync("/hangfire"); // Hangfire dashboard middleware возвращает 401 без auth — это NOT a 200 // (если бы было 200 — это значит filter не сработал и /hangfire утёк). ((int)resp.StatusCode).Should().BeOneOf(401, 403, 404); } [Fact] public async Task Tenant_admin_cannot_access_hangfire() { var actor = new ApiActor(_factory.CreateClient()); await actor.SignupAndLoginAsync($"ha-{Guid.NewGuid():N}"); var resp = await actor.Http.GetAsync("/hangfire"); // 401/403 — фильтр сработал; 404 — Hangfire выключен в тестах // (нет UseHangfireDashboard'а). Любой из этих кодов — это «доступа нет», // именно то что мы хотим проверить. ((int)resp.StatusCode).Should().BeOneOf(401, 403, 404); } }