using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.AspNetCore.TestHost;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using SameBeat.Infrastructure.BazaDanych;
using Xunit;
namespace SameBeat.Tests.Integration;
///
/// Regresja ETAP 7 -- to jest test, ktorego brak zglosil arbiter audytu: bez niego ktos moglby
/// przypadkiem usunac [Authorize] z StanImprezyHub.DolaczDoGrupyHosta przy refaktorze i "dotnet test"
/// by tego nie zlapal. Uruchamia CALA aplikacje przez WebApplicationFactory (TestServer, bez
/// prawdziwej sieci) i nawiazuje prawdziwe polaczenie SignalR (transport LongPolling -- TestServer
/// nie wspiera natywnych WebSocketow) przez ten sam potok HTTP co reszta testow integracyjnych.
///
public class StanImprezyHubAutoryzacjaTests : IClassFixture>
{
private readonly WebApplicationFactory _fabryka;
public StanImprezyHubAutoryzacjaTests(WebApplicationFactory fabryka)
{
_fabryka = fabryka.WithWebHostBuilder(builder =>
{
builder.UseEnvironment("Testing");
builder.ConfigureServices(services =>
{
var deskryptorKontekstu = services.SingleOrDefault(s => s.ServiceType == typeof(DbContextOptions));
if (deskryptorKontekstu is not null)
{
services.Remove(deskryptorKontekstu);
}
services.AddDbContext(opcje =>
opcje.UseInMemoryDatabase("StanImprezyHubAutoryzacjaTests"));
});
});
}
[Fact]
public async Task DolaczDoGrupyHosta_BezZalogowania_OdrzucaWywolanieNieRozlaczajacPolaczenia()
{
var serwer = _fabryka.Server;
await using var polaczenie = new HubConnectionBuilder()
.WithUrl("http://localhost/hub/impreza", opcje =>
{
opcje.HttpMessageHandlerFactory = _ => serwer.CreateHandler();
opcje.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.LongPolling;
})
.Build();
await polaczenie.StartAsync();
// BRAK ciasteczka sb_auth -- to jest dokladnie przypadek anonimowego widza probujacego
// dolaczyc do kanalu sterowania hosta.
var wyjatek = await Assert.ThrowsAsync(
() => polaczenie.InvokeAsync("DolaczDoGrupyHosta"));
Assert.NotNull(wyjatek);
// Kluczowe: odrzucenie [Authorize] NIE zrywa calego polaczenia (klient dalej jest widzem
// w grupie "widzowie") -- to potwierdza, ze polaczenie przetrwalo odrzucone wywolanie.
Assert.Equal(HubConnectionState.Connected, polaczenie.State);
await polaczenie.StopAsync();
}
}