using System.Reflection; using Omika.Core.Observability; using Omika.Core.Observability.Diagnostic; namespace Omika.Tests.Observability.Diagnostic; /// /// Contrôle qu'aucune donnée sensible (mot de passe, token, identifiant matériel…) /// n'est exposée par le modèle d'événement ni écrite par l'exporteur local. /// Objectif : prévenir une future régression générée par IA. /// public class DiagnosticDataSafetyTests { private static readonly string[] ForbiddenNames = [ "Password", "Token", "Authorization", "EmailBody", "ConnectionString", "IMEI", "MACAddress", "AdvertisingId", "IMSI", "SerialNumber", "Fingerprint" ]; [Fact] public void OmikaEvent_ExposesNoSensitiveProperty() { string[] names = typeof(OmikaEvent).GetProperties().Select(p => p.Name).ToArray(); foreach (string forbidden in ForbiddenNames) { Assert.DoesNotContain(names, n => n.Contains(forbidden, StringComparison.OrdinalIgnoreCase)); } } [Fact] public void DeviceInfoSnapshot_ExposesNoSensitiveProperty() { string[] names = typeof(DeviceInfoSnapshot).GetProperties().Select(p => p.Name).ToArray(); foreach (string forbidden in ForbiddenNames) { Assert.DoesNotContain(names, n => n.Contains(forbidden, StringComparison.OrdinalIgnoreCase)); } } [Fact] public async Task StandardEvent_JsonContainsNoSensitiveKey() { string dir = DiagnosticTestHarness.CreateTempDirectory(); try { var exporter = new LocalFileTelemetryExporter(new LocalDiagnosticOptions { Directory = dir }); await exporter.ExportAsync([new TelemetryEvent { EventCode = TelemetryEventCodes.MobileAppStarted, Component = "test" }]); await exporter.DisposeAsync(); string json = File.ReadAllText(Assert.Single(Directory.EnumerateFiles(dir, "*.jsonl"))); foreach (string forbidden in ForbiddenNames) { Assert.DoesNotContain(forbidden, json, StringComparison.OrdinalIgnoreCase); } } finally { DiagnosticTestHarness.DeleteDirectory(dir); } } }