Files
SIG-CM2.0/tests/SIGCM2.Application.Tests/Pricing/ChargeableChars/CreateChargeableCharConfigCommandValidatorTests.cs

146 lines
5.3 KiB
C#
Raw Normal View History

using FluentValidation.TestHelper;
using Microsoft.Extensions.Time.Testing;
using SIGCM2.Application.Pricing.ChargeableChars.Create;
using SIGCM2.Domain.Pricing.ChargeableChars;
namespace SIGCM2.Application.Tests.Pricing.ChargeableChars;
/// <summary>
/// PRC-001 — Validator tests for CreateChargeableCharConfigCommand.
/// Covers: Symbol length, Category enum, PricePerUnit > 0, ValidFrom >= today_AR.
/// </summary>
public class CreateChargeableCharConfigCommandValidatorTests
{
private readonly FakeTimeProvider _time = new(new DateTimeOffset(2026, 4, 20, 12, 0, 0, TimeSpan.Zero));
private readonly CreateChargeableCharConfigCommandValidator _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 CreateChargeableCharConfigCommandValidatorTests()
{
_validator = new CreateChargeableCharConfigCommandValidator(_time);
}
private static CreateChargeableCharConfigCommand ValidCmd() => new(
MedioId: null,
Symbol: "$",
Category: ChargeableCharCategories.Currency,
PricePerUnit: 1.0m,
ValidFrom: Today);
// ── Symbol ───────────────────────────────────────────────────────────────────
[Fact]
public void Symbol_Empty_FailsValidation()
{
var cmd = ValidCmd() with { Symbol = "" };
_validator.TestValidate(cmd).ShouldHaveValidationErrorFor(x => x.Symbol);
}
[Fact]
public void Symbol_TooLong_FailsValidation()
{
// max 4 chars
var cmd = ValidCmd() with { Symbol = "ABCDE" };
_validator.TestValidate(cmd).ShouldHaveValidationErrorFor(x => x.Symbol);
}
[Fact]
public void Symbol_SingleChar_Passes()
{
var cmd = ValidCmd() with { Symbol = "$" };
_validator.TestValidate(cmd).ShouldNotHaveValidationErrorFor(x => x.Symbol);
}
[Fact]
public void Symbol_FourChars_Passes()
{
var cmd = ValidCmd() with { Symbol = "ABCD" };
_validator.TestValidate(cmd).ShouldNotHaveValidationErrorFor(x => x.Symbol);
}
// ── Category ─────────────────────────────────────────────────────────────────
[Fact]
public void Category_Invalid_FailsValidation()
{
var cmd = ValidCmd() with { Category = "Unknown" };
_validator.TestValidate(cmd).ShouldHaveValidationErrorFor(x => x.Category);
}
[Fact]
public void Category_Empty_FailsValidation()
{
var cmd = ValidCmd() with { Category = "" };
_validator.TestValidate(cmd).ShouldHaveValidationErrorFor(x => x.Category);
}
[Theory]
[InlineData("Currency")]
[InlineData("Percentage")]
[InlineData("Exclamation")]
[InlineData("Question")]
[InlineData("Other")]
public void Category_ValidValues_Pass(string category)
{
var cmd = ValidCmd() with { Category = category };
_validator.TestValidate(cmd).ShouldNotHaveValidationErrorFor(x => x.Category);
}
// ── 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()
{
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);
}
// ── Happy path ────────────────────────────────────────────────────────────────
[Fact]
public void ValidCommand_PassesAllRules()
{
_validator.TestValidate(ValidCmd()).ShouldNotHaveAnyValidationErrors();
}
}