using Marathon.Domain.Enums;
using Marathon.Domain.ValueObjects;
using Marathon.UI.Services;
namespace Marathon.UI.Tests.Support;
///
/// In-memory for bUnit tests.
/// Seed via / .
///
public sealed class FakeAnomalyBrowsingService : IAnomalyBrowsingService
{
public List Items { get; } = new();
public AnomalyDetailVm? Detail { get; set; }
public List SportCodes { get; } = new();
public int UnreadCount { get; set; }
public int ListCallCount { get; private set; }
public AnomalyFilter? LastFilter { get; private set; }
public Task> ListAsync(AnomalyFilter filter, CancellationToken ct)
{
ListCallCount++;
LastFilter = filter;
IEnumerable q = Items;
if (filter.MinSeverity is { } min)
{
q = q.Where(i => AnomalySeverityRules.MeetsThreshold(i.Severity, min));
}
if (filter.SportCodes is { Count: > 0 } sports)
{
q = q.Where(i => sports.Contains(i.Sport.Value));
}
if (filter.From is { } from) q = q.Where(i => i.DetectedAt >= from);
if (filter.To is { } to) q = q.Where(i => i.DetectedAt <= to);
return Task.FromResult>(
q.OrderByDescending(static i => i.DetectedAt).ToList());
}
public Task GetByIdAsync(Guid id, CancellationToken ct)
=> Task.FromResult(Detail);
public Task GetUnreadCountAsync(DateTimeOffset since, CancellationToken ct)
=> Task.FromResult(UnreadCount);
public Task> ListKnownSportCodesAsync(CancellationToken ct)
=> Task.FromResult>(SportCodes);
/// Builds an for tests with sane defaults.
public static AnomalyListItem MakeItem(
Guid? id = null,
string eventCode = "EV-A",
string title = "Arsenal vs Chelsea",
int sport = 11,
string country = "ENG",
string league = "Premier",
DateTimeOffset? detectedAt = null,
decimal score = 0.55m,
int gapSeconds = 90,
decimal? preWin1 = 1.30m,
decimal? preDraw = null,
decimal? preWin2 = 4.00m,
decimal? postWin1 = 4.00m,
decimal? postDraw = null,
decimal? postWin2 = 1.30m,
AnomalyFavourite preFav = AnomalyFavourite.Side1,
AnomalyFavourite postFav = AnomalyFavourite.Side2,
bool isTwoWay = true)
=> new(
id ?? Guid.NewGuid(),
new EventId(eventCode),
title,
new SportCode(sport),
country,
league,
detectedAt ?? DateTimeOffset.UtcNow.AddMinutes(-2),
score,
AnomalySeverityRules.FromScore(score),
AnomalyKind.SuspensionFlip,
gapSeconds,
preWin1,
preDraw,
preWin2,
postWin1,
postDraw,
postWin2,
preFav,
postFav,
isTwoWay);
public static AnomalyEvidenceSnapshot MakeSnapshot(
DateTimeOffset? capturedAt = null,
decimal? rate1 = 1.30m,
decimal? rateDraw = null,
decimal? rate2 = 4.00m,
decimal? p1 = 0.755m,
decimal? pDraw = null,
decimal? p2 = 0.245m,
AnomalyFavourite favourite = AnomalyFavourite.Side1)
=> new(
capturedAt ?? DateTimeOffset.UtcNow.AddMinutes(-3),
rate1,
rateDraw,
rate2,
p1,
pDraw,
p2,
favourite);
}