using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using SQLInsight.Agent.Hub;
using SQLInsight.Hub.Data;
using SQLInsight.Repository;
namespace SQLInsight.IntegrationTests;
/// A support case from SQLInsight Web, through the agent to the hub and its status back again.
[Collection(SqlServerTestGroup.Name)]
[Trait("Category", "Integration")]
public class HubSupportEndToEndTests(SqlServerFixture sql, HubFixture hub) : IClassFixture, IAsyncLifetime
{
private readonly string _database = "SQLInsightSupE2E_" + Guid.NewGuid().ToString("N")[..8];
private InsightRepository _repository = null!;
public async Task InitializeAsync()
{
await sql.ExecuteAsSaAsync($"CREATE DATABASE [{_database}];");
_repository = new InsightRepository(sql.DatabaseConnectionString(_database));
await _repository.MigrateAsync();
}
public Task DisposeAsync() => sql.ExecuteAsSaAsync($"ALTER DATABASE [{_database}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [{_database}];");
private sealed class TestServerClients(Func create) : IHttpClientFactory
{
public HttpClient CreateClient(string name) => create();
}
private HubSyncService Sync(string license)
{
var options = Options.Create(new HubOptions { Enabled = true, Url = new Uri("http://localhost/"), License = license });
options.Value.TrustedKeys[HubFixture.KeyId] = hub.PublicKey;
return new HubSyncService(options, _repository, new TestServerClients(() => hub.Factory.CreateClient()), TimeProvider.System, NullLogger.Instance);
}
[Fact]
public async Task Case_filed_in_web_gets_a_number_and_its_closing_comes_back()
{
var customer = $"Support E2E {Guid.NewGuid():N}"[..28];
var license = hub.License(customer);
await _repository.AddSupportRequestAsync(new NewSupportRequest(Guid.NewGuid(), "Langsom backup", "Siden mandag", "Anna", "anna@kunde.dk", null, "KUNDE\\anna"), DateTimeOffset.UtcNow);
await Sync(license).RunOnceAsync(CancellationToken.None);
var filed = Assert.Single(await _repository.GetSupportCasesAsync());
Assert.Equal(("SUP-000001", SupportCaseStatus.Open), (filed.Reference, filed.Status));
await using (var scope = hub.Factory.Services.CreateAsyncScope())
{
var db = scope.ServiceProvider.GetRequiredService();
var stored = await db.SupportCases.SingleAsync(c => c.Customer!.Name == customer);
stored.IsOpen = false;
stored.ClosedAt = DateTime.UtcNow;
await db.SaveChangesAsync();
}
await Sync(license).RunOnceAsync(CancellationToken.None);
var closed = Assert.Single(await _repository.GetSupportCasesAsync());
Assert.Equal(SupportCaseStatus.Closed, closed.Status);
Assert.NotNull(closed.ClosedAt);
}
[Fact]
public async Task Request_the_license_does_not_cover_is_given_up()
{
var customer = $"Community {Guid.NewGuid():N}"[..24];
await _repository.AddSupportRequestAsync(new NewSupportRequest(Guid.NewGuid(), "Hjælp", null, "Anna", "anna@kunde.dk", null, null), DateTimeOffset.UtcNow);
var sync = Sync(hub.License(customer));
await sync.SyncSupportCasesAsync(hub.Factory.CreateClient(), new HubOptions { Url = new Uri("http://localhost/"), License = hub.License(customer, SQLInsight.Licensing.LicensePlan.Community) }, CancellationToken.None);
var failed = Assert.Single(await _repository.GetSupportCasesAsync());
Assert.Equal(SupportCaseStatus.Failed, failed.Status);
Assert.Contains("403", failed.LastError, StringComparison.Ordinal);
}
}