250 lines
8.9 KiB
C#
250 lines
8.9 KiB
C#
using Omika.Diagnostics.Models;
|
|
using Omika.Diagnostics.Queries;
|
|
using Omika.Diagnostics.Tests.Fakes;
|
|
|
|
namespace Omika.Diagnostics.Tests;
|
|
|
|
/// <summary>
|
|
/// Tâche 7 — Versions applicatives : résumés par version et totaux. Tests sur
|
|
/// <see cref="FakeDiagnosticEventRepository"/> ; la production exécute la même sémantique
|
|
/// via COUNT/FILTER/MIN/MAX/COUNT(DISTINCT) côté PostgreSQL.
|
|
/// </summary>
|
|
public class DiagnosticVersionTests
|
|
{
|
|
private static readonly DateTimeOffset From = new(2025, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
|
private static readonly DateTimeOffset To = new(2025, 2, 1, 0, 0, 0, TimeSpan.Zero);
|
|
|
|
private static DiagnosticEventRecord Ev(
|
|
string eventCode = "TEST",
|
|
DateTimeOffset? ts = null,
|
|
string? appVersion = null,
|
|
string level = "Info",
|
|
string? platform = null) =>
|
|
new()
|
|
{
|
|
EventId = Guid.NewGuid(),
|
|
EventCode = eventCode,
|
|
TimestampUtc = ts ?? From.AddMinutes(1),
|
|
AppVersion = appVersion,
|
|
Level = level,
|
|
Priority = "P2",
|
|
Platform = platform,
|
|
Source = DiagnosticSources.Mobile,
|
|
IngestedAtUtc = DateTimeOffset.UtcNow
|
|
};
|
|
|
|
private static DiagnosticAggregateQuery All(int limit = DiagnosticAggregateDefaults.MaxLimit) =>
|
|
new() { FromUtc = From, ToUtc = To, Limit = limit };
|
|
|
|
// ------------------------------------------------- V1 : deux versions ----
|
|
[Fact]
|
|
public async Task GetVersionSummaries_TwoVersions_TwoSummaries()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev("A", appVersion: "1.0.0"),
|
|
Ev("B", appVersion: "2.0.0")
|
|
});
|
|
|
|
IReadOnlyList<DiagnosticVersionSummary> result = await repo.GetVersionSummariesAsync(All());
|
|
|
|
Assert.Equal(2, result.Count);
|
|
}
|
|
|
|
// ------------------------------------------------- V2 : EventCount ----
|
|
[Fact]
|
|
public async Task GetVersionSummaries_EventCount_IsCorrect()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev("A", appVersion: "1.0.0"),
|
|
Ev("B", appVersion: "1.0.0"),
|
|
Ev("C", appVersion: "1.0.0"),
|
|
Ev("D", appVersion: "2.0.0")
|
|
});
|
|
|
|
IReadOnlyList<DiagnosticVersionSummary> result = await repo.GetVersionSummariesAsync(All());
|
|
|
|
DiagnosticVersionSummary v1 = Assert.Single(result, x => x.AppVersion == "1.0.0");
|
|
Assert.Equal(3, v1.EventCount);
|
|
}
|
|
|
|
// --------------------------------- V3 : ErrorCount casse mixte ----
|
|
[Fact]
|
|
public async Task GetVersionSummaries_ErrorCount_HandlesMixedCase()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev("A", appVersion: "1.0.0", level: "Error"),
|
|
Ev("B", appVersion: "1.0.0", level: "error"), // minuscule
|
|
Ev("C", appVersion: "1.0.0", level: "Critical"),
|
|
Ev("D", appVersion: "1.0.0", level: "Info")
|
|
});
|
|
|
|
IReadOnlyList<DiagnosticVersionSummary> result = await repo.GetVersionSummariesAsync(All());
|
|
|
|
DiagnosticVersionSummary v1 = Assert.Single(result);
|
|
Assert.Equal(3, v1.ErrorCount); // Error + error + Critical ; Info exclu
|
|
}
|
|
|
|
// --------------------------------- V4 : FirstSeen/LastSeen ----
|
|
[Fact]
|
|
public async Task GetVersionSummaries_FirstAndLastSeen_AreCorrect()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev("A", From.AddMinutes(10), appVersion: "1.0.0"),
|
|
Ev("B", From.AddMinutes(5), appVersion: "1.0.0"),
|
|
Ev("C", From.AddMinutes(20), appVersion: "1.0.0")
|
|
});
|
|
|
|
IReadOnlyList<DiagnosticVersionSummary> result = await repo.GetVersionSummariesAsync(All());
|
|
|
|
DiagnosticVersionSummary v1 = Assert.Single(result);
|
|
Assert.Equal(From.AddMinutes(5), v1.FirstSeenUtc);
|
|
Assert.Equal(From.AddMinutes(20), v1.LastSeenUtc);
|
|
}
|
|
|
|
// --------------------------------- V5 : PlatformCount distinct ----
|
|
[Fact]
|
|
public async Task GetVersionSummaries_PlatformCount_IsDistinct()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev("A", appVersion: "1.0.0", platform: "Android"),
|
|
Ev("B", appVersion: "1.0.0", platform: "Android"),
|
|
Ev("C", appVersion: "1.0.0", platform: "iOS")
|
|
});
|
|
|
|
IReadOnlyList<DiagnosticVersionSummary> result = await repo.GetVersionSummariesAsync(All());
|
|
|
|
DiagnosticVersionSummary v1 = Assert.Single(result);
|
|
Assert.Equal(2, v1.PlatformCount); // Android + iOS (distinct)
|
|
}
|
|
|
|
// --------------------------------- V6 : version null exclue ----
|
|
[Fact]
|
|
public async Task GetVersionSummaries_NullVersion_IsExcluded()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev("A", appVersion: "1.0.0"),
|
|
Ev("B", appVersion: null),
|
|
Ev("C", appVersion: string.Empty)
|
|
});
|
|
|
|
IReadOnlyList<DiagnosticVersionSummary> result = await repo.GetVersionSummariesAsync(All());
|
|
|
|
DiagnosticVersionSummary v1 = Assert.Single(result);
|
|
Assert.Equal("1.0.0", v1.AppVersion);
|
|
}
|
|
|
|
// --------------------------------- V7 : période appliquée ----
|
|
[Fact]
|
|
public async Task GetVersionSummaries_RespectsPeriod()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev("A", From.AddMinutes(-5), appVersion: "1.0.0"), // avant → exclu
|
|
Ev("B", From.AddMinutes(5), appVersion: "2.0.0"), // dans
|
|
Ev("C", To.AddMinutes(5), appVersion: "3.0.0") // après → exclu
|
|
});
|
|
|
|
IReadOnlyList<DiagnosticVersionSummary> result = await repo.GetVersionSummariesAsync(All());
|
|
|
|
DiagnosticVersionSummary v = Assert.Single(result);
|
|
Assert.Equal("2.0.0", v.AppVersion);
|
|
}
|
|
|
|
// --------------------------------- V8 : limit appliqué ----
|
|
[Fact]
|
|
public async Task GetVersionSummaries_RespectsLimit()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev("A", appVersion: "1.0.0"),
|
|
Ev("B", appVersion: "2.0.0"),
|
|
Ev("C", appVersion: "3.0.0")
|
|
});
|
|
|
|
IReadOnlyList<DiagnosticVersionSummary> result = await repo.GetVersionSummariesAsync(
|
|
new DiagnosticAggregateQuery { FromUtc = From, ToUtc = To, Limit = 2 });
|
|
|
|
Assert.Equal(2, result.Count);
|
|
}
|
|
|
|
// --------------------------------- V9 : tri déterministe ----
|
|
[Fact]
|
|
public async Task GetVersionSummaries_SortsByEventCountThenVersion()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev("A", appVersion: "1.0.0"),
|
|
Ev("B", appVersion: "2.0.0"),
|
|
Ev("C", appVersion: "2.0.0")
|
|
});
|
|
|
|
IReadOnlyList<DiagnosticVersionSummary> result = await repo.GetVersionSummariesAsync(All());
|
|
|
|
Assert.Equal(new[] { "2.0.0", "1.0.0" }, result.Select(x => x.AppVersion).ToArray());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetVersionSummaries_EqualCounts_TieBreaksByVersion()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev("A", appVersion: "1.0.0"),
|
|
Ev("B", appVersion: "2.0.0")
|
|
});
|
|
|
|
IReadOnlyList<DiagnosticVersionSummary> result = await repo.GetVersionSummariesAsync(All());
|
|
|
|
Assert.Equal(new[] { "1.0.0", "2.0.0" }, result.Select(x => x.AppVersion).ToArray());
|
|
}
|
|
|
|
// --------------------------------- V10 : aucune donnée ----
|
|
[Fact]
|
|
public async Task GetVersionSummaries_NoData_ReturnsEmpty()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
|
|
IReadOnlyList<DiagnosticVersionSummary> result = await repo.GetVersionSummariesAsync(All());
|
|
|
|
Assert.Empty(result);
|
|
}
|
|
|
|
// --------------------------------- Totals ----
|
|
[Fact]
|
|
public async Task GetVersionTotals_ReturnsAllCounters()
|
|
{
|
|
var repo = new FakeDiagnosticEventRepository();
|
|
await repo.InsertBatchAsync(new[]
|
|
{
|
|
Ev("A", appVersion: "1.0.0"),
|
|
Ev("B", appVersion: "1.0.0"),
|
|
Ev("C", appVersion: "2.0.0"),
|
|
Ev("D", appVersion: "2.0.0", level: "Error"),
|
|
Ev("E", appVersion: null),
|
|
Ev("F", appVersion: string.Empty)
|
|
});
|
|
|
|
DiagnosticVersionTotals totals = await repo.GetVersionTotalsAsync(All());
|
|
|
|
Assert.Equal(2, totals.DistinctVersionCount);
|
|
Assert.Equal(4, totals.VersionedEventCount);
|
|
Assert.Equal(1, totals.VersionedErrorCount);
|
|
Assert.Equal(2, totals.MissingVersionCount);
|
|
}
|
|
}
|