fix(telemetry): first-party fetch for play/share, beacon only on unload
Route normal play closes (end/switch/stop) and all shares through a same-origin HttpClient POST so privacy-hardened browsers stop blocking them; keep sendBeacon for the tab-unload edge. Rename the JS module off telemetry/beacon to session/ lifecycle so the retained fallback isn't name-matched. No new data or identifiers.
This commit is contained in:
@@ -1,33 +1,27 @@
|
||||
using DeepDrftModels.Enums;
|
||||
using DeepDrftPublic.Client.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using Microsoft.JSInterop.Infrastructure;
|
||||
|
||||
namespace DeepDrftTests;
|
||||
|
||||
/// <summary>
|
||||
/// Unit tests for the Phase 16 share tracker (<see cref="ShareTracker"/>): the per-(target,channel)
|
||||
/// debounce (§1b — at most one event per target+channel per 60s window per session). The tracker fires
|
||||
/// through a beacon that wraps <see cref="IJSRuntime"/>; the tests use a no-op JS runtime (the send is
|
||||
/// through the first-party <see cref="IEventPoster"/>; the tests use a no-op poster (the POST is
|
||||
/// fire-and-forget and its outcome is irrelevant) and assert on the debounce decision via the bool the
|
||||
/// recorder returns — true when an event fired, false when debounced.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ShareTrackerTests
|
||||
{
|
||||
// sendBeacon interop is fire-and-forget; the tracker never reads the result, so a no-op runtime that
|
||||
// returns default for any invocation is sufficient to exercise the debounce logic.
|
||||
private sealed class NoopJsRuntime : IJSRuntime
|
||||
// The first-party POST is fire-and-forget; the tracker never reads the result, so a no-op poster that
|
||||
// completes immediately is sufficient to exercise the debounce logic.
|
||||
private sealed class NoopEventPoster : IEventPoster
|
||||
{
|
||||
public ValueTask<TValue> InvokeAsync<TValue>(string identifier, object?[]? args)
|
||||
=> ValueTask.FromResult<TValue>(default!);
|
||||
|
||||
public ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToken cancellationToken, object?[]? args)
|
||||
=> ValueTask.FromResult<TValue>(default!);
|
||||
public Task PostAsync(string url, string json) => Task.CompletedTask;
|
||||
}
|
||||
|
||||
// Minimal NavigationManager so the tracker can compose the (unused-in-test) beacon URL.
|
||||
// Minimal NavigationManager so the tracker can compose the (unused-in-test) event URL.
|
||||
private sealed class TestNavigationManager : NavigationManager
|
||||
{
|
||||
public TestNavigationManager() => Initialize("https://deepdrft.test/", "https://deepdrft.test/");
|
||||
@@ -49,7 +43,7 @@ public class ShareTrackerTests
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
=> _tracker = new ShareTracker(
|
||||
new BeaconInterop(new NoopJsRuntime()),
|
||||
new NoopEventPoster(),
|
||||
new StubAnonIdProvider("anon-1"),
|
||||
new TestNavigationManager());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user