using AutopilotMonitor.Functions.Functions.Reports;
using AutopilotMonitor.Shared.DataAccess;
namespace AutopilotMonitor.Functions.Tests;
///
/// Tests for the hardware rejection aggregation logic extracted from GetHardwareRejectedFunction.
/// All tests target the pure static BuildAggregatedResult method — no HTTP or DI needed.
///
public class GetHardwareRejectedFunctionTests
{
private static readonly DateTime T0 = new(2026, 3, 1, 12, 0, 0, DateTimeKind.Utc);
// =========================================================================
// Empty / no matching reports
// =========================================================================
[Fact]
public void BuildAggregatedResult_EmptyList_ReturnsEmpty()
{
var (aggregated, totalRawReports) = GetHardwareRejectedFunction.BuildAggregatedResult([]);
Assert.Empty(aggregated);
Assert.Equal(0, totalRawReports);
}
[Fact]
public void BuildAggregatedResult_FiltersHardwareNotAllowedOnly()
{
var reports = new List
{
MakeEntry("HardwareNotAllowed", "Dell", "Latitude", "SN1", T0),
MakeEntry("CertificateExpired", "Dell", "Latitude", "SN2", T0.AddMinutes(1)),
MakeEntry("Timeout", "HP", "EliteBook", "SN3", T0.AddMinutes(2)),
};
var (aggregated, totalRawReports) = GetHardwareRejectedFunction.BuildAggregatedResult(reports);
Assert.Single(aggregated);
Assert.Equal(1, totalRawReports);
}
// =========================================================================
// Aggregation logic
// =========================================================================
[Fact]
public void BuildAggregatedResult_AggregatesCaseInsensitive()
{
var reports = new List
{
MakeEntry("HardwareNotAllowed", "Dell", "Latitude 5520", "SN1", T0),
MakeEntry("HardwareNotAllowed", "DELL", "LATITUDE 5520", "SN2", T0.AddMinutes(1)),
MakeEntry("HardwareNotAllowed", "dell", "latitude 5520", "SN3", T0.AddMinutes(2)),
};
var (aggregated, _) = GetHardwareRejectedFunction.BuildAggregatedResult(reports);
Assert.Single(aggregated);
var item = aggregated[0];
Assert.Equal(3, (int)item.AttemptCount);
}
[Fact]
public void BuildAggregatedResult_CountsAttemptsCorrectly()
{
var reports = new List
{
MakeEntry("HardwareNotAllowed", "Dell", "Latitude", "SN1", T0),
MakeEntry("HardwareNotAllowed", "Dell", "Latitude", "SN2", T0.AddMinutes(1)),
MakeEntry("HardwareNotAllowed", "Dell", "Latitude", "SN3", T0.AddMinutes(2)),
MakeEntry("HardwareNotAllowed", "HP", "EliteBook", "SN4", T0.AddMinutes(3)),
};
var (aggregated, totalRawReports) = GetHardwareRejectedFunction.BuildAggregatedResult(reports);
Assert.Equal(4, totalRawReports);
Assert.Equal(2, aggregated.Count);
var dell = aggregated.First(a => a.Manufacturer.Equals("Dell", StringComparison.OrdinalIgnoreCase));
Assert.Equal(3, (int)dell.AttemptCount);
}
[Fact]
public void BuildAggregatedResult_CountsUniqueSerials()
{
var reports = new List
{
MakeEntry("HardwareNotAllowed", "Dell", "Latitude", "SN1", T0),
MakeEntry("HardwareNotAllowed", "Dell", "Latitude", "SN1", T0.AddMinutes(1)), // duplicate
MakeEntry("HardwareNotAllowed", "Dell", "Latitude", "sn1", T0.AddMinutes(2)), // duplicate (case)
MakeEntry("HardwareNotAllowed", "Dell", "Latitude", "SN2", T0.AddMinutes(3)),
};
var (aggregated, _) = GetHardwareRejectedFunction.BuildAggregatedResult(reports);
var item = aggregated[0];
Assert.Equal(2, (int)item.UniqueSerials);
Assert.Equal(4, (int)item.AttemptCount);
}
[Fact]
public void BuildAggregatedResult_LimitsSampleSerialsToFive()
{
var reports = Enumerable.Range(1, 8)
.Select(i => MakeEntry("HardwareNotAllowed", "Dell", "Latitude", $"SN{i}", T0.AddMinutes(i)))
.ToList();
var (aggregated, _) = GetHardwareRejectedFunction.BuildAggregatedResult(reports);
var item = aggregated[0];
var samples = (IEnumerable