using Tau.Acuvim.Portal.DTOs; using Tau.Acuvim.Portal.Services; namespace Tau.Acuvim.Portal.Tests; public class TariffValidatorTests { private static UpsertTariffRequest Valid(params TariffPeriodDto[] periods) => new( Name: "Domestic 2026", EffectiveFrom: new DateOnly(2026, 1, 1), EffectiveTo: null, DefaultRatePerKwh: 2.50m, FixedMonthlyCharge: 100m, VatPercentage: 15m, IsActive: true, Periods: periods); [Fact] public void Valid_NoPeriods_ReturnsNull() { Assert.Null(TariffValidator.Validate(Valid())); } [Fact] public void Valid_WithGoodPeriod_ReturnsNull() { var period = new TariffPeriodDto("Peak", DaysOfWeek: 31, StartTime: "17:00", EndTime: "20:00", RatePerKwh: 3.50m); Assert.Null(TariffValidator.Validate(Valid(period))); } [Fact] public void EmptyName_Errors() { var req = Valid() with { Name = " " }; Assert.Contains("Tariff name is required", TariffValidator.Validate(req)); } [Fact] public void EffectiveTo_BeforeFrom_Errors() { var req = Valid() with { EffectiveTo = new DateOnly(2025, 12, 31) }; Assert.Contains("EffectiveTo must be on or after", TariffValidator.Validate(req)); } [Fact] public void NegativeRate_Errors() { var req = Valid() with { DefaultRatePerKwh = -0.01m }; Assert.Contains("DefaultRatePerKwh", TariffValidator.Validate(req)); } [Fact] public void NegativeFixedCharge_Errors() { var req = Valid() with { FixedMonthlyCharge = -1m }; Assert.Contains("FixedMonthlyCharge", TariffValidator.Validate(req)); } [Theory] [InlineData(-0.01)] [InlineData(100.01)] public void VatOutOfRange_Errors(double vat) { var req = Valid() with { VatPercentage = (decimal)vat }; Assert.Contains("VatPercentage", TariffValidator.Validate(req)); } [Fact] public void PeriodEmptyName_Errors() { var bad = new TariffPeriodDto("", 31, "00:00", "08:00", 1m); Assert.Contains("Period name is required", TariffValidator.Validate(Valid(bad))); } [Fact] public void PeriodZeroDays_Errors() { var bad = new TariffPeriodDto("Peak", 0, "17:00", "20:00", 3m); Assert.Contains("at least one day", TariffValidator.Validate(Valid(bad))); } [Fact] public void PeriodMidnightWrap_Errors() { var bad = new TariffPeriodDto("Overnight", 31, "22:00", "06:00", 1m); Assert.Contains("no midnight wrap", TariffValidator.Validate(Valid(bad))); } [Fact] public void PeriodEqualStartEnd_Errors() { var bad = new TariffPeriodDto("Zero", 31, "10:00", "10:00", 1m); Assert.Contains("StartTime must be before EndTime", TariffValidator.Validate(Valid(bad))); } [Fact] public void PeriodNegativeRate_Errors() { var bad = new TariffPeriodDto("Peak", 31, "17:00", "20:00", -0.1m); Assert.Contains("RatePerKwh", TariffValidator.Validate(Valid(bad))); } [Fact] public void PeriodBadTimeFormat_Errors() { var bad = new TariffPeriodDto("Peak", 31, "25:00", "20:00", 3m); Assert.Contains("invalid times", TariffValidator.Validate(Valid(bad))); } }