188 lines
6.9 KiB
C#
188 lines
6.9 KiB
C#
using Omika.Diagnostics.Models;
|
|
using Omika.Diagnostics.Tests.Fakes;
|
|
using Omika.Diagnostics.Web.Pages;
|
|
|
|
namespace Omika.Diagnostics.Tests;
|
|
|
|
/// <summary>
|
|
/// T17-E — PageModel /Parc : vue générale, répartitions, liste appareils, filtres,
|
|
/// pagination, drill-down et réattribution de licence. Testés sans HttpContext
|
|
/// (constructeur repository uniquement, comme les autres PageModels).
|
|
/// </summary>
|
|
public class DiagnosticParcModelTests
|
|
{
|
|
private static DiagnosticEventRecord Ev(
|
|
long id,
|
|
string deviceKey,
|
|
DateTimeOffset ts,
|
|
string? client = null,
|
|
string? license = null,
|
|
string? platform = "Android",
|
|
string? os = "Android",
|
|
string? osVersion = "15",
|
|
string? manufacturer = null,
|
|
string? model = null,
|
|
string? appVersion = null)
|
|
{
|
|
DiagnosticEventRecord e = DiagnosticTestData.Event(Guid.NewGuid(), timestamp: ts);
|
|
e.Id = id;
|
|
e.DeviceKey = deviceKey;
|
|
e.ClientCode = client;
|
|
e.LicenseNumber = license;
|
|
e.Platform = platform;
|
|
e.OperatingSystem = os;
|
|
e.OperatingSystemVersion = osVersion;
|
|
e.DeviceManufacturer = manufacturer;
|
|
e.DeviceModel = model;
|
|
e.AppVersion = appVersion;
|
|
return e;
|
|
}
|
|
|
|
// ------------------------------- vue générale + répartitions ----
|
|
[Fact]
|
|
public async Task ParcModel_LoadsOverviewAndDistributions()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
DateTimeOffset now = DateTimeOffset.UtcNow;
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev(1, "d1", now.AddMinutes(-60), platform: "Android", osVersion: "16", manufacturer: "Xiaomi"),
|
|
Ev(2, "d2", now.AddMinutes(-50), platform: "iOS", os: "iOS", osVersion: "18.5", manufacturer: "Apple"),
|
|
Ev(3, "d3", now.AddMinutes(-40), platform: "Android", osVersion: "15", manufacturer: "Samsung")
|
|
});
|
|
|
|
var model = new ParcModel(repo);
|
|
await model.OnGetAsync();
|
|
|
|
Assert.True(model.PostgreSqlAvailable);
|
|
Assert.True(model.HasData);
|
|
Assert.Equal(3, model.ActiveDevices);
|
|
Assert.Equal(2, model.AndroidDevices);
|
|
Assert.Equal(1, model.IosDevices);
|
|
Assert.Equal(0, model.DesktopDevices);
|
|
Assert.Equal(3, model.Devices.Count);
|
|
Assert.NotEmpty(model.ManufacturerDistribution);
|
|
Assert.NotEmpty(model.OsVersionDistribution);
|
|
}
|
|
|
|
// ------------------------------- réattribution de licence ----
|
|
[Fact]
|
|
public async Task ParcModel_LicenseReassigned_ShowsTwoDevices()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
DateTimeOffset now = DateTimeOffset.UtcNow;
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev(1, "dev-a", now.AddDays(-20), license: "LIC-001", manufacturer: "Samsung", model: "SM-DEMO"),
|
|
Ev(2, "dev-b", now.AddDays(-1), license: "LIC-001", manufacturer: "Apple", model: "iPhoneDemo", os: "iOS", osVersion: "18")
|
|
});
|
|
|
|
var model = new ParcModel(repo);
|
|
await model.OnGetAsync();
|
|
|
|
Assert.Equal(2, model.ActiveDevices);
|
|
Assert.Equal(2, model.Devices.Count);
|
|
Assert.Contains(model.Devices, d => d.DeviceKey == "dev-a");
|
|
Assert.Contains(model.Devices, d => d.DeviceKey == "dev-b");
|
|
|
|
// « Appareils observés par licence » : LIC-001 → 2 appareils distincts, jamais 1.
|
|
Omika.Diagnostics.Queries.DeviceDistribution lic = Assert.Single(model.LicenseDistribution);
|
|
Assert.Equal("LIC-001", lic.Key);
|
|
Assert.Equal(2, lic.DeviceCount);
|
|
}
|
|
|
|
// ------------------------------- filtre licence ----
|
|
[Fact]
|
|
public async Task ParcModel_LicenseFilter_ReturnsOnlyMatchingDevices()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
DateTimeOffset now = DateTimeOffset.UtcNow;
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev(1, "dev-a", now.AddMinutes(-30), license: "LIC-A"),
|
|
Ev(2, "dev-b", now.AddMinutes(-20), license: "LIC-A"),
|
|
Ev(3, "dev-c", now.AddMinutes(-10), license: "LIC-B")
|
|
});
|
|
|
|
var model = new ParcModel(repo) { LicenseNumber = "LIC-A" };
|
|
await model.OnGetAsync();
|
|
|
|
Assert.Equal(2, model.ActiveDevices);
|
|
Assert.All(model.Devices, d => Assert.Equal("LIC-A", d.LicenseNumber));
|
|
}
|
|
|
|
// ------------------------------- filtre client + plateforme ----
|
|
[Fact]
|
|
public async Task ParcModel_ClientAndPlatformFilters_Combine()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
DateTimeOffset now = DateTimeOffset.UtcNow;
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev(1, "d1", now.AddMinutes(-60), client: "CLIENT-A", platform: "Android"),
|
|
Ev(2, "d2", now.AddMinutes(-50), client: "CLIENT-A", platform: "iOS", os: "iOS"),
|
|
Ev(3, "d3", now.AddMinutes(-40), client: "CLIENT-B", platform: "Android")
|
|
});
|
|
|
|
var model = new ParcModel(repo) { ClientCode = "CLIENT-A", Platform = "Android" };
|
|
await model.OnGetAsync();
|
|
|
|
Assert.Equal(1, model.ActiveDevices);
|
|
Omika.Diagnostics.Queries.DeviceFleetRecord device = Assert.Single(model.Devices);
|
|
Assert.Equal("d1", device.DeviceKey);
|
|
}
|
|
|
|
// ------------------------------- pagination / Route ----
|
|
[Fact]
|
|
public void ParcModel_Route_PreservesFilters()
|
|
{
|
|
var model = new ParcModel(new FakeDiagnosticEventRepository())
|
|
{
|
|
ClientCode = "CLIENT-A",
|
|
LicenseNumber = "LIC-A",
|
|
Platform = "Android",
|
|
Manufacturer = "Samsung"
|
|
};
|
|
|
|
Dictionary<string, string> route = model.Route(2);
|
|
|
|
Assert.Equal("2", route["pageNumber"]);
|
|
Assert.Equal("CLIENT-A", route["clientCode"]);
|
|
Assert.Equal("LIC-A", route["licenseNumber"]);
|
|
Assert.Equal("Android", route["platform"]);
|
|
Assert.Equal("Samsung", route["manufacturer"]);
|
|
}
|
|
|
|
// ------------------------------- zéro appareil ----
|
|
[Fact]
|
|
public async Task ParcModel_NoDevices_HasDataFalse()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
var model = new ParcModel(repo);
|
|
await model.OnGetAsync();
|
|
|
|
Assert.False(model.HasData);
|
|
Assert.Equal(0, model.ActiveDevices);
|
|
Assert.Empty(model.Devices);
|
|
}
|
|
|
|
// ------------------------------- pourcentage formaté ----
|
|
[Fact]
|
|
public async Task ParcModel_FormatPercentage_NoNaN()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
DateTimeOffset now = DateTimeOffset.UtcNow;
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev(1, "d1", now.AddMinutes(-60), platform: "Android"),
|
|
Ev(2, "d2", now.AddMinutes(-50), platform: "iOS", os: "iOS")
|
|
});
|
|
|
|
var model = new ParcModel(repo);
|
|
await model.OnGetAsync();
|
|
|
|
Assert.Equal(2, model.ActiveDevices);
|
|
Assert.Equal("50 %", model.FormatPercentage(1));
|
|
}
|
|
}
|