Files
Omika/tests/Omika.Tests/Observability/ScreenUsageTelemetryTests.cs
T
2026-10-23 18:46:50 +02:00

122 lines
4.6 KiB
C#

using Omika.App.Diagnostics;
using Omika.App.Navigation;
using Omika.Core.Observability;
using Omika.Core.Observability.Diagnostic;
namespace Omika.Tests.Observability;
/// <summary>
/// T18 (§73/§74/§75/§77) : une navigation logique génère EXACTEMENT un ScreenView ;
/// le retour = nouvelle vue ; le refresh/même page ne multiplie pas les événements ;
/// l'écran initial est émis une fois. L'émission est centralisée dans
/// <see cref="ScreenUsageTelemetry"/> (jamais par ViewModel).
/// </summary>
public class ScreenUsageTelemetryTests
{
[Fact]
public void TrackInitialScreen_EmitsSingleScreenView_ForCurrentPage()
{
var navigation = new NavigationService();
var capturing = new CapturingTelemetry();
var tracker = new ScreenUsageTelemetry(navigation, capturing, null);
tracker.TrackInitialScreen();
OmikaEvent evt = Assert.Single(capturing.Events);
Assert.Equal(TelemetryEventCodes.MobileScreenView, evt.EventCode);
Assert.Equal(DiagnosticScreenCodes.Agenda, evt.ScreenCode);
Assert.Null(evt.FeatureCode);
}
[Fact]
public void Navigate_EmitsExactlyOneScreenView_ForTarget()
{
var navigation = new NavigationService();
var capturing = new CapturingTelemetry();
var tracker = new ScreenUsageTelemetry(navigation, capturing, null);
tracker.TrackInitialScreen();
capturing.Clear();
navigation.NavigateTo(AppPage.SiteDetail);
OmikaEvent evt = Assert.Single(capturing.Events);
Assert.Equal(TelemetryEventCodes.MobileScreenView, evt.EventCode);
Assert.Equal(DiagnosticScreenCodes.SiteDetail, evt.ScreenCode);
}
[Fact]
public void Return_IsANewScreenView()
{
var navigation = new NavigationService();
var capturing = new CapturingTelemetry();
var tracker = new ScreenUsageTelemetry(navigation, capturing, null);
tracker.TrackInitialScreen(); // AGENDA (1)
navigation.NavigateTo(AppPage.SiteDetail); // SITE_DETAIL (2)
navigation.GoBack(); // AGENDA (3)
Assert.Equal(3, capturing.Events.Count);
Assert.Equal(DiagnosticScreenCodes.Agenda, capturing.Events[0].ScreenCode);
Assert.Equal(DiagnosticScreenCodes.SiteDetail, capturing.Events[1].ScreenCode);
Assert.Equal(DiagnosticScreenCodes.Agenda, capturing.Events[2].ScreenCode);
}
[Fact]
public void Refresh_OrSamePage_DoesNotEmitAnotherScreenView()
{
var navigation = new NavigationService();
var capturing = new CapturingTelemetry();
var tracker = new ScreenUsageTelemetry(navigation, capturing, null);
tracker.TrackInitialScreen(); // AGENDA (1)
navigation.NavigateTo(AppPage.SiteDetail); // SITE_DETAIL (2)
// Même page (paramètre identique ou différent) : NavigationService ne lève
// pas PageChanged (seulement ParameterChanged) → aucun ScreenView.
navigation.NavigateTo(AppPage.SiteDetail);
navigation.NavigateTo(AppPage.SiteDetail, new object());
Assert.Equal(2, capturing.Events.Count);
}
[Fact]
public void Navigate_SetsCurrentScreenOnDiagnosticContext()
{
var navigation = new NavigationService();
var capturing = new CapturingTelemetry();
var context = new DiagnosticContext(new DiagnosticSession(), new DeviceInfoSnapshot());
var tracker = new ScreenUsageTelemetry(navigation, capturing, context);
tracker.TrackInitialScreen();
navigation.NavigateTo(AppPage.InterventionDetail);
Assert.Equal(DiagnosticScreenCodes.InterventionDetail, context.ScreenCode);
}
[Fact]
public void UnknownPage_DoesNotEmit()
{
var navigation = new NavigationService();
var capturing = new CapturingTelemetry();
var tracker = new ScreenUsageTelemetry(navigation, capturing, null);
// Aucune page inconnue n'est navigable, mais le tracker reste fail-open :
// la navigation vers une page non résolue n'émet rien.
tracker.TrackInitialScreen();
capturing.Clear();
navigation.NavigateTo(AppPage.Parametres);
Assert.Single(capturing.Events);
Assert.Equal(DiagnosticScreenCodes.Settings, capturing.Events[0].ScreenCode);
}
private sealed class CapturingTelemetry : IOmikaTelemetry
{
public List<OmikaEvent> Events { get; } = [];
public void Track(TelemetryEvent telemetryEvent) => Events.Add(telemetryEvent);
public void Log(DiagnosticEvent diagnosticEvent) => Events.Add(diagnosticEvent);
public void Clear() => Events.Clear();
}
}