Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user