147 lines
4.7 KiB
C#
147 lines
4.7 KiB
C#
using App.Core.Entities.Maintenance;
|
|
using App.Core.Services.Kpi;
|
|
|
|
namespace App.Core.Tests.Kpi;
|
|
|
|
public class KpiCalculatorTests
|
|
{
|
|
[Fact]
|
|
public void ComputeMtbfHours_LessThanTwoFailures_ReturnsNull()
|
|
{
|
|
var timestamps = new List<DateTime> { new(2026, 1, 1) };
|
|
|
|
Assert.Null(KpiCalculator.ComputeMtbfHours(timestamps));
|
|
Assert.Null(KpiCalculator.ComputeMtbfHours(new List<DateTime>()));
|
|
}
|
|
|
|
[Fact]
|
|
public void ComputeMtbfHours_AveragesIntervalsBetweenFailures()
|
|
{
|
|
// Pannes le 1er, le 3 (48h après) et le 8 (120h après) -> moyenne (48+120)/2 = 84h.
|
|
var timestamps = new List<DateTime>
|
|
{
|
|
new(2026, 1, 1),
|
|
new(2026, 1, 3),
|
|
new(2026, 1, 8),
|
|
};
|
|
|
|
var mtbf = KpiCalculator.ComputeMtbfHours(timestamps);
|
|
|
|
Assert.Equal(84, mtbf);
|
|
}
|
|
|
|
[Fact]
|
|
public void ComputeMttrHours_NoCompletedCorrective_ReturnsNull()
|
|
{
|
|
var workOrders = new List<WorkOrder>
|
|
{
|
|
new() { Type = WorkOrderType.Corrective, Status = WorkOrderStatus.InProgress, CreatedAtUtc = DateTime.UtcNow, MachineId = 1, ScheduledDate = DateOnly.FromDateTime(DateTime.UtcNow) },
|
|
};
|
|
|
|
Assert.Null(KpiCalculator.ComputeMttrHours(workOrders));
|
|
}
|
|
|
|
[Fact]
|
|
public void ComputeMttrHours_AveragesRepairDuration()
|
|
{
|
|
var created = new DateTime(2026, 1, 1, 8, 0, 0, DateTimeKind.Utc);
|
|
var workOrders = new List<WorkOrder>
|
|
{
|
|
new()
|
|
{
|
|
Type = WorkOrderType.Corrective,
|
|
Status = WorkOrderStatus.Done,
|
|
MachineId = 1,
|
|
ScheduledDate = DateOnly.FromDateTime(created),
|
|
CreatedAtUtc = created,
|
|
CompletedAtUtc = created.AddHours(4),
|
|
},
|
|
new()
|
|
{
|
|
Type = WorkOrderType.Corrective,
|
|
Status = WorkOrderStatus.Done,
|
|
MachineId = 1,
|
|
ScheduledDate = DateOnly.FromDateTime(created),
|
|
CreatedAtUtc = created,
|
|
CompletedAtUtc = created.AddHours(8),
|
|
},
|
|
};
|
|
|
|
Assert.Equal(6, KpiCalculator.ComputeMttrHours(workOrders));
|
|
}
|
|
|
|
[Fact]
|
|
public void ComputeAvailabilityPercent_NullInputs_ReturnsNull()
|
|
{
|
|
Assert.Null(KpiCalculator.ComputeAvailabilityPercent(null, 5));
|
|
Assert.Null(KpiCalculator.ComputeAvailabilityPercent(5, null));
|
|
}
|
|
|
|
[Fact]
|
|
public void ComputeAvailabilityPercent_ComputesClassicFormula()
|
|
{
|
|
// MTBF=90, MTTR=10 -> 90/(90+10) = 90%
|
|
var availability = KpiCalculator.ComputeAvailabilityPercent(90, 10);
|
|
|
|
Assert.Equal(90.0, availability);
|
|
}
|
|
|
|
[Fact]
|
|
public void ComputeMaintenanceCost_SumsPartsAndLabor()
|
|
{
|
|
var parts = new List<(decimal UnitPrice, double Quantity)>
|
|
{
|
|
(10.00m, 3), // 30
|
|
(5.50m, 2), // 11
|
|
};
|
|
|
|
var cost = KpiCalculator.ComputeMaintenanceCost(parts, laborCost: 100m);
|
|
|
|
Assert.Equal(141.00m, cost);
|
|
}
|
|
|
|
[Fact]
|
|
public void ComputePreventiveComplianceRatePercent_NoClosedOrders_ReturnsNull()
|
|
{
|
|
var workOrders = new List<WorkOrder>
|
|
{
|
|
new() { Type = WorkOrderType.Preventive, Status = WorkOrderStatus.ToDo, MachineId = 1, ScheduledDate = new DateOnly(2026, 1, 1), CreatedAtUtc = DateTime.UtcNow },
|
|
};
|
|
|
|
Assert.Null(KpiCalculator.ComputePreventiveComplianceRatePercent(workOrders));
|
|
}
|
|
|
|
[Fact]
|
|
public void ComputePreventiveComplianceRatePercent_CountsOnTimeVsLate()
|
|
{
|
|
var workOrders = new List<WorkOrder>
|
|
{
|
|
// Clôturé avant échéance -> dans les temps
|
|
new()
|
|
{
|
|
Type = WorkOrderType.Preventive, Status = WorkOrderStatus.Done, MachineId = 1,
|
|
ScheduledDate = new DateOnly(2026, 1, 10), CreatedAtUtc = DateTime.UtcNow,
|
|
CompletedAtUtc = new DateTime(2026, 1, 9),
|
|
},
|
|
// Clôturé après échéance -> en retard
|
|
new()
|
|
{
|
|
Type = WorkOrderType.Preventive, Status = WorkOrderStatus.Done, MachineId = 1,
|
|
ScheduledDate = new DateOnly(2026, 1, 10), CreatedAtUtc = DateTime.UtcNow,
|
|
CompletedAtUtc = new DateTime(2026, 1, 15),
|
|
},
|
|
// Curatif : ignoré du calcul
|
|
new()
|
|
{
|
|
Type = WorkOrderType.Corrective, Status = WorkOrderStatus.Done, MachineId = 1,
|
|
ScheduledDate = new DateOnly(2026, 1, 10), CreatedAtUtc = DateTime.UtcNow,
|
|
CompletedAtUtc = new DateTime(2026, 1, 20),
|
|
},
|
|
};
|
|
|
|
var rate = KpiCalculator.ComputePreventiveComplianceRatePercent(workOrders);
|
|
|
|
Assert.Equal(50.0, rate);
|
|
}
|
|
}
|