using System.Reflection; using Omika.Core.Observability; using Omika.Diagnostics.Referential; namespace Omika.Diagnostics.Tests; /// /// Tâche 12 — Référentiels : libellés EventCode/ErrorCode, fallbacks « non documenté », /// couverture du catalogue producteur (C5), alignement niveaux (C6) et priorités (C7). /// public class DiagnosticReferentialTests { // ------------------------------------------------------- C1 : EventCode connu ---- [Fact] public void EventCode_Known_ReturnsFrenchLabel() { DiagnosticEventCodeDefinition? def = DiagnosticEventCodeCatalog.TryGet("OMK-WKR-SYNC-002"); Assert.NotNull(def); Assert.Equal("Échec de synchronisation Worker", def.LibelleFrancais); Assert.Equal("Synchronisation", def.Famille); Assert.Equal("Omika.Worker", def.Producteur); } // ------------------------------------------------- C2 : EventCode inconnu → fallback ---- [Fact] public void EventCode_Unknown_ReturnsFallbackWithoutThrowing() { Assert.Null(DiagnosticEventCodeCatalog.TryGet("NEW_EVENT_001")); DiagnosticEventCodeDefinition resolved = DiagnosticEventCodeCatalog.Resolve("NEW_EVENT_001"); Assert.Equal("NEW_EVENT_001", resolved.Code); Assert.Equal("Code événement non documenté", resolved.DescriptionFrancais); } // ------------------------------------------------------ C3 : ErrorCode connu ---- [Fact] public void ErrorCode_Known_ReturnsDefinition() { DiagnosticErrorCodeDefinition? unhandled = DiagnosticErrorCodeCatalog.TryGet("UnhandledException"); Assert.NotNull(unhandled); Assert.Equal("Exception non gérée", unhandled.LibelleFrancais); Assert.Equal(DiagnosticErrorCodeCatalog.OrigineProduction, unhandled.Origine); // Indisponibilité réseau mobile : erreur la plus fréquente en production, elle // doit être lisible par le support (et non « Code erreur non documenté »). DiagnosticErrorCodeDefinition? reseau = DiagnosticErrorCodeCatalog.TryGet("HttpRequestException"); Assert.NotNull(reseau); Assert.Equal("Réseau indisponible", reseau.LibelleFrancais); Assert.Equal(DiagnosticErrorCodeCatalog.OrigineProduction, reseau.Origine); // Code de seed local signalé comme tel. DiagnosticErrorCodeDefinition? timeout = DiagnosticErrorCodeCatalog.TryGet("TIMEOUT"); Assert.NotNull(timeout); Assert.Equal("Délai dépassé", timeout.LibelleFrancais); Assert.Equal(DiagnosticErrorCodeCatalog.OrigineTestLocal, timeout.Origine); } // ------------------------------------------------ C4 : ErrorCode inconnu → fallback ---- [Fact] public void ErrorCode_Unknown_ReturnsFallbackWithoutThrowing() { Assert.Null(DiagnosticErrorCodeCatalog.TryGet("NEW_ERR_001")); DiagnosticErrorCodeDefinition resolved = DiagnosticErrorCodeCatalog.Resolve("NEW_ERR_001"); Assert.Equal("NEW_ERR_001", resolved.Code); Assert.Equal("Code erreur non documenté", resolved.DescriptionFrancais); } // ------------------- C5 : tous les EventCodes du catalogue producteur sont couverts ---- [Fact] public void EveryProducerEventCode_HasCatalogEntry() { IReadOnlyList producerCodes = typeof(TelemetryEventCodes) .GetFields(BindingFlags.Public | BindingFlags.Static) .Where(f => f.FieldType == typeof(EventCode)) .Select(f => ((EventCode)f.GetValue(null)!).Value) .Where(v => v is not null) .Select(v => v!) .ToList(); Assert.NotEmpty(producerCodes); foreach (string code in producerCodes) { Assert.True( DiagnosticEventCodeCatalog.TryGet(code) is not null, $"EventCode producteur non documenté dans le catalogue : {code}"); } } // ---------- Les codes middleware (hors TelemetryEventCodes) sont documentés ---- [Fact] public void MiddlewareEventCodes_AreDocumented() { Assert.NotNull(DiagnosticEventCodeCatalog.TryGet("API_HTTP_ERROR")); Assert.NotNull(DiagnosticEventCodeCatalog.TryGet("API_HTTP_4XX")); } // -------------------------------------- C6 : niveaux UI ↔ valeurs backend ---- [Fact] public void LevelCatalog_MatchesTelemetryLevelEnum() { string[] technical = DiagnosticLevelCatalog.All.Select(l => l.ValeurTechnique).ToArray(); string[] producer = Enum.GetNames(); Assert.Equal(producer, technical); } // ------------------------------------------- C7 : priorités P0–P4 ---- [Fact] public void PriorityCatalog_MatchesP0ToP4() { string[] priorities = DiagnosticPriorityCatalog.All.Select(p => p.Valeur).ToArray(); Assert.Equal(new[] { "P0", "P1", "P2", "P3", "P4" }, priorities); Assert.Equal(Enum.GetNames(), priorities); } }