Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
using System.Text.Json;
|
||||
using Omika.Core.Observability.External;
|
||||
using Omika.Diagnostics.Import;
|
||||
using Omika.Diagnostics.Models;
|
||||
using Omika.Diagnostics.Queries;
|
||||
using Omika.Diagnostics.Tests.Fakes;
|
||||
|
||||
namespace Omika.Diagnostics.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Tâche 13-A — Socle de stockage ClientCode / ServerInstance / Environment :
|
||||
/// compatibilité additive (NULL), conservation des valeurs, lecture/écriture du
|
||||
/// repository (fake) et filtres backend paramétrés (miroir du repository réel).
|
||||
/// Aucun PostgreSQL réel requis (même convention que les autres tests, §51).
|
||||
/// </summary>
|
||||
public class DiagnosticClientContextTests
|
||||
{
|
||||
private static readonly DateTimeOffset From = new(2025, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
||||
|
||||
// --------------------------- A1 : ancien record sans contexte --------------
|
||||
[Fact]
|
||||
public void A1_RecordWithoutContext_AllContextFieldsAreNull()
|
||||
{
|
||||
DiagnosticEventRecord record = DiagnosticTestData.Event(Guid.NewGuid(), "OLD");
|
||||
|
||||
Assert.Null(record.ClientCode);
|
||||
Assert.Null(record.ServerInstance);
|
||||
Assert.Null(record.Environment);
|
||||
}
|
||||
|
||||
// --------------------------- A2/A3/A4 : conservation d'une valeur ----------
|
||||
[Fact]
|
||||
public void A2_RecordWithClientCode_PreservesValue()
|
||||
{
|
||||
DiagnosticEventRecord record = EventWithContext(Guid.NewGuid(), clientCode: "CLIENT-A");
|
||||
|
||||
Assert.Equal("CLIENT-A", record.ClientCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A3_RecordWithServerInstance_PreservesValue()
|
||||
{
|
||||
DiagnosticEventRecord record = EventWithContext(Guid.NewGuid(), serverInstance: "API-SRV-01");
|
||||
|
||||
Assert.Equal("API-SRV-01", record.ServerInstance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A4_RecordWithEnvironment_PreservesValue()
|
||||
{
|
||||
DiagnosticEventRecord record = EventWithContext(Guid.NewGuid(), environment: "Production");
|
||||
|
||||
Assert.Equal("Production", record.Environment);
|
||||
}
|
||||
|
||||
// --------------------------- A5 : insert avec les trois valeurs -------------
|
||||
[Fact]
|
||||
public async Task A5_InsertWithAllThreeValues_StoresAndReadsThem()
|
||||
{
|
||||
var repo = new FakeDiagnosticEventRepository();
|
||||
DiagnosticEventRecord record = EventWithContext(Guid.NewGuid(), "CLIENT-A", "API-SRV-01", "Production");
|
||||
record.Id = 42;
|
||||
|
||||
int inserted = await repo.InsertBatchAsync(new[] { record });
|
||||
|
||||
Assert.Equal(1, inserted);
|
||||
DiagnosticEventRecord? read = await repo.GetByIdAsync(42);
|
||||
Assert.NotNull(read);
|
||||
Assert.Equal("CLIENT-A", read!.ClientCode);
|
||||
Assert.Equal("API-SRV-01", read.ServerInstance);
|
||||
Assert.Equal("Production", read.Environment);
|
||||
}
|
||||
|
||||
// --------------------------- A6 : insert NULL compatible --------------------
|
||||
[Fact]
|
||||
public async Task A6_InsertWithNullContext_IsAcceptedAndReadsNull()
|
||||
{
|
||||
var repo = new FakeDiagnosticEventRepository();
|
||||
DiagnosticEventRecord record = EventWithContext(Guid.NewGuid(), null, null, null);
|
||||
record.Id = 7;
|
||||
|
||||
int inserted = await repo.InsertBatchAsync(new[] { record });
|
||||
|
||||
Assert.Equal(1, inserted);
|
||||
DiagnosticEventRecord? read = await repo.GetByIdAsync(7);
|
||||
Assert.NotNull(read);
|
||||
Assert.Null(read!.ClientCode);
|
||||
Assert.Null(read.ServerInstance);
|
||||
Assert.Null(read.Environment);
|
||||
}
|
||||
|
||||
// --------------------------- A7 : lecture repository restitue les valeurs ----
|
||||
[Fact]
|
||||
public async Task A7_QueryAsync_RestoresContextValues()
|
||||
{
|
||||
var repo = new FakeDiagnosticEventRepository();
|
||||
DiagnosticEventRecord record = EventWithContext(Guid.NewGuid(), "CLIENT-B", "API-SRV-02", "Staging");
|
||||
record.Id = 10;
|
||||
await repo.InsertBatchAsync(new[] { record });
|
||||
|
||||
DiagnosticQueryResult<DiagnosticEventRecord> result = await repo.QueryAsync(new DiagnosticEventQuery());
|
||||
|
||||
DiagnosticEventRecord read = Assert.Single(result.Items);
|
||||
Assert.Equal("CLIENT-B", read.ClientCode);
|
||||
Assert.Equal("API-SRV-02", read.ServerInstance);
|
||||
Assert.Equal("Staging", read.Environment);
|
||||
}
|
||||
|
||||
// --------------------------- A8 : ancien JSONL / source absente → NULL ------
|
||||
[Fact]
|
||||
public void A8_Mapper_OldRecordWithoutContext_LeavesContextNull()
|
||||
{
|
||||
// RemoteDiagnosticRecord expose désormais ClientCode/ServerInstance/Environment
|
||||
// (T13-B), mais un ancien enregistrement sans contexte porte ces champs à null :
|
||||
// le mapper doit les laisser NULL (aucune valeur inventée).
|
||||
RemoteDiagnosticRecord old = DiagnosticTestData.Record(Guid.NewGuid(), "OLD");
|
||||
|
||||
DiagnosticEventRecord? mapped = DiagnosticEventRecordMapper.ToRecord(old, "mobile");
|
||||
|
||||
Assert.NotNull(mapped);
|
||||
Assert.Null(mapped!.ClientCode);
|
||||
Assert.Null(mapped.ServerInstance);
|
||||
Assert.Null(mapped.Environment);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A8_OldJsonlLineWithoutContextFields_DeserializesAndMapsToNull()
|
||||
{
|
||||
RemoteDiagnosticRecord old = DiagnosticTestData.Record(Guid.NewGuid(), "OLD");
|
||||
string line = DiagnosticTestData.SerializeLine(old);
|
||||
|
||||
// Aucun champ « ClientCode/ServerInstance/Environment » requis : la ligne
|
||||
// ancienne (sans ces champs) doit être acceptée telle quelle (§20).
|
||||
RemoteDiagnosticRecord? parsed =
|
||||
JsonSerializer.Deserialize<RemoteDiagnosticRecord>(line, new JsonSerializerOptions(JsonSerializerDefaults.Web));
|
||||
|
||||
Assert.NotNull(parsed);
|
||||
DiagnosticEventRecord? mapped = DiagnosticEventRecordMapper.ToRecord(parsed, "mobile");
|
||||
Assert.NotNull(mapped);
|
||||
Assert.Null(mapped!.ClientCode);
|
||||
Assert.Null(mapped.ServerInstance);
|
||||
Assert.Null(mapped.Environment);
|
||||
}
|
||||
|
||||
// --------------------------- A9/A10/A11 : filtres backend -------------------
|
||||
[Fact]
|
||||
public async Task A9_ClientCodeFilter_ReturnsOnlyMatching()
|
||||
{
|
||||
var repo = new FakeDiagnosticEventRepository();
|
||||
await repo.InsertBatchAsync(new[]
|
||||
{
|
||||
EventWithContext(Guid.NewGuid(), "CLIENT-A", "SRV-1", "Prod", From.AddMinutes(1)),
|
||||
EventWithContext(Guid.NewGuid(), "CLIENT-B", "SRV-1", "Prod", From.AddMinutes(2))
|
||||
});
|
||||
|
||||
DiagnosticQueryResult<DiagnosticEventRecord> result =
|
||||
await repo.QueryAsync(new DiagnosticEventQuery { ClientCode = "CLIENT-A" });
|
||||
|
||||
Assert.Single(result.Items);
|
||||
Assert.Equal("CLIENT-A", result.Items[0].ClientCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task A10_ServerInstanceFilter_ReturnsOnlyMatching()
|
||||
{
|
||||
var repo = new FakeDiagnosticEventRepository();
|
||||
await repo.InsertBatchAsync(new[]
|
||||
{
|
||||
EventWithContext(Guid.NewGuid(), "CLIENT-A", "SRV-1", "Prod", From.AddMinutes(1)),
|
||||
EventWithContext(Guid.NewGuid(), "CLIENT-A", "SRV-2", "Prod", From.AddMinutes(2))
|
||||
});
|
||||
|
||||
DiagnosticQueryResult<DiagnosticEventRecord> result =
|
||||
await repo.QueryAsync(new DiagnosticEventQuery { ServerInstance = "SRV-2" });
|
||||
|
||||
Assert.Single(result.Items);
|
||||
Assert.Equal("SRV-2", result.Items[0].ServerInstance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task A11_EnvironmentFilter_ReturnsOnlyMatching()
|
||||
{
|
||||
var repo = new FakeDiagnosticEventRepository();
|
||||
await repo.InsertBatchAsync(new[]
|
||||
{
|
||||
EventWithContext(Guid.NewGuid(), "CLIENT-A", "SRV-1", "Production", From.AddMinutes(1)),
|
||||
EventWithContext(Guid.NewGuid(), "CLIENT-A", "SRV-1", "Staging", From.AddMinutes(2))
|
||||
});
|
||||
|
||||
DiagnosticQueryResult<DiagnosticEventRecord> result =
|
||||
await repo.QueryAsync(new DiagnosticEventQuery { Environment = "Staging" });
|
||||
|
||||
Assert.Single(result.Items);
|
||||
Assert.Equal("Staging", result.Items[0].Environment);
|
||||
}
|
||||
|
||||
private static DiagnosticEventRecord EventWithContext(
|
||||
Guid id,
|
||||
string? clientCode = null,
|
||||
string? serverInstance = null,
|
||||
string? environment = null,
|
||||
DateTimeOffset? timestamp = null)
|
||||
{
|
||||
DiagnosticEventRecord record = DiagnosticTestData.Event(id, "TEST", timestamp);
|
||||
record.ClientCode = clientCode;
|
||||
record.ServerInstance = serverInstance;
|
||||
record.Environment = environment;
|
||||
return record;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user