102 lines
3.9 KiB
C#
102 lines
3.9 KiB
C#
using FluentValidation.TestHelper;
|
|
using Microsoft.Extensions.Time.Testing;
|
|
using SIGCM2.Application.Pricing.ChargeableChars.SchedulePrice;
|
|
|
|
namespace SIGCM2.Application.Tests.Pricing.ChargeableChars;
|
|
|
|
/// <summary>
|
|
/// PRC-001 — Validator tests for SchedulePriceChangeCommand.
|
|
/// Covers: PricePerUnit > 0, ValidFrom >= today_AR.
|
|
/// Forward-only check (ValidFrom > existing.ValidFrom) is done in handler, not validator.
|
|
/// </summary>
|
|
public class SchedulePriceChangeCommandValidatorTests
|
|
{
|
|
private readonly FakeTimeProvider _time = new(new DateTimeOffset(2026, 4, 20, 12, 0, 0, TimeSpan.Zero));
|
|
private readonly SchedulePriceChangeCommandValidator _validator;
|
|
|
|
private static readonly DateOnly Today = new(2026, 4, 20);
|
|
private static readonly DateOnly Yesterday = new(2026, 4, 19);
|
|
private static readonly DateOnly Tomorrow = new(2026, 4, 21);
|
|
|
|
public SchedulePriceChangeCommandValidatorTests()
|
|
{
|
|
_validator = new SchedulePriceChangeCommandValidator(_time);
|
|
}
|
|
|
|
private static SchedulePriceChangeCommand ValidCmd() => new(
|
|
Id: 1L,
|
|
PricePerUnit: 2.0m,
|
|
ValidFrom: Tomorrow);
|
|
|
|
// ── PricePerUnit ─────────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void PricePerUnit_Zero_FailsValidation()
|
|
{
|
|
var cmd = ValidCmd() with { PricePerUnit = 0m };
|
|
_validator.TestValidate(cmd).ShouldHaveValidationErrorFor(x => x.PricePerUnit);
|
|
}
|
|
|
|
[Fact]
|
|
public void PricePerUnit_Negative_FailsValidation()
|
|
{
|
|
var cmd = ValidCmd() with { PricePerUnit = -1m };
|
|
_validator.TestValidate(cmd).ShouldHaveValidationErrorFor(x => x.PricePerUnit);
|
|
}
|
|
|
|
[Fact]
|
|
public void PricePerUnit_Positive_Passes()
|
|
{
|
|
var cmd = ValidCmd() with { PricePerUnit = 0.01m };
|
|
_validator.TestValidate(cmd).ShouldNotHaveValidationErrorFor(x => x.PricePerUnit);
|
|
}
|
|
|
|
// ── ValidFrom ────────────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void ValidFrom_InPast_FailsValidation()
|
|
{
|
|
var cmd = ValidCmd() with { ValidFrom = Yesterday };
|
|
_validator.TestValidate(cmd).ShouldHaveValidationErrorFor(x => x.ValidFrom);
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidFrom_Today_Passes()
|
|
{
|
|
// today is valid — forward-only check vs existing row is done in handler
|
|
var cmd = ValidCmd() with { ValidFrom = Today };
|
|
_validator.TestValidate(cmd).ShouldNotHaveValidationErrorFor(x => x.ValidFrom);
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidFrom_Future_Passes()
|
|
{
|
|
var cmd = ValidCmd() with { ValidFrom = Tomorrow };
|
|
_validator.TestValidate(cmd).ShouldNotHaveValidationErrorFor(x => x.ValidFrom);
|
|
}
|
|
|
|
// ── Id ───────────────────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void Id_Zero_FailsValidation()
|
|
{
|
|
var cmd = ValidCmd() with { Id = 0L };
|
|
_validator.TestValidate(cmd).ShouldHaveValidationErrorFor(x => x.Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Id_Positive_Passes()
|
|
{
|
|
var cmd = ValidCmd() with { Id = 1L };
|
|
_validator.TestValidate(cmd).ShouldNotHaveValidationErrorFor(x => x.Id);
|
|
}
|
|
|
|
// ── Happy path ────────────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void ValidCommand_PassesAllRules()
|
|
{
|
|
_validator.TestValidate(ValidCmd()).ShouldNotHaveAnyValidationErrors();
|
|
}
|
|
}
|