147 lines
4.9 KiB
C#
147 lines
4.9 KiB
C#
|
|
using FluentAssertions;
|
||
|
|
using SIGCM2.Domain.Exceptions;
|
||
|
|
using SIGCM2.Domain.Pricing.Exceptions;
|
||
|
|
|
||
|
|
namespace SIGCM2.Application.Tests.Domain.Pricing.Exceptions;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// PRC-001 — T2.1 Domain unit tests for Pricing exceptions.
|
||
|
|
/// Verifies constructor props, message content, and DomainException inheritance.
|
||
|
|
/// </summary>
|
||
|
|
public sealed class PricingExceptionTests
|
||
|
|
{
|
||
|
|
// ── EmojiDetectedException ────────────────────────────────────────────────
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void EmojiDetectedException_SetsDetectedCodepoint()
|
||
|
|
{
|
||
|
|
var ex = new EmojiDetectedException(0x1F697); // 🚗
|
||
|
|
|
||
|
|
ex.DetectedCodepoint.Should().Be(0x1F697);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void EmojiDetectedException_MessageContainsCodepoint()
|
||
|
|
{
|
||
|
|
var ex = new EmojiDetectedException(0x1F697);
|
||
|
|
|
||
|
|
ex.Message.Should().NotBeNullOrWhiteSpace();
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void EmojiDetectedException_InheritsFromDomainException()
|
||
|
|
{
|
||
|
|
var ex = new EmojiDetectedException(0x1F697);
|
||
|
|
|
||
|
|
ex.Should().BeAssignableTo<DomainException>();
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── WordCountValidationException ─────────────────────────────────────────
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void WordCountValidationException_SetsFieldAndReason()
|
||
|
|
{
|
||
|
|
var ex = new WordCountValidationException("rawText", "El texto supera el máximo de 2000 caracteres.");
|
||
|
|
|
||
|
|
ex.Field.Should().Be("rawText");
|
||
|
|
ex.Reason.Should().Be("El texto supera el máximo de 2000 caracteres.");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void WordCountValidationException_MessageContainsFieldAndReason()
|
||
|
|
{
|
||
|
|
var ex = new WordCountValidationException("rawText", "supera el máximo");
|
||
|
|
|
||
|
|
ex.Message.Should().Contain("rawText");
|
||
|
|
ex.Message.Should().Contain("supera el máximo");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void WordCountValidationException_InheritsFromDomainException()
|
||
|
|
{
|
||
|
|
var ex = new WordCountValidationException("field", "reason");
|
||
|
|
|
||
|
|
ex.Should().BeAssignableTo<DomainException>();
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── ChargeableCharConfigInvalidException ─────────────────────────────────
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void ChargeableCharConfigInvalidException_SetsFieldAndReason()
|
||
|
|
{
|
||
|
|
var ex = new ChargeableCharConfigInvalidException("PricePerUnit", "debe ser > 0");
|
||
|
|
|
||
|
|
ex.Field.Should().Be("PricePerUnit");
|
||
|
|
ex.Reason.Should().Be("debe ser > 0");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void ChargeableCharConfigInvalidException_MessageContainsFieldAndReason()
|
||
|
|
{
|
||
|
|
var ex = new ChargeableCharConfigInvalidException("Symbol", "no puede estar vacío");
|
||
|
|
|
||
|
|
ex.Message.Should().Contain("Symbol");
|
||
|
|
ex.Message.Should().Contain("no puede estar vacío");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void ChargeableCharConfigInvalidException_InheritsFromDomainException()
|
||
|
|
{
|
||
|
|
var ex = new ChargeableCharConfigInvalidException("field", "reason");
|
||
|
|
|
||
|
|
ex.Should().BeAssignableTo<DomainException>();
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── ChargeableCharConfigForwardOnlyException ──────────────────────────────
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void ChargeableCharConfigForwardOnlyException_SetsAllProperties()
|
||
|
|
{
|
||
|
|
var newVf = new DateOnly(2026, 3, 1);
|
||
|
|
var activeVf = new DateOnly(2026, 4, 1);
|
||
|
|
|
||
|
|
var ex = new ChargeableCharConfigForwardOnlyException(
|
||
|
|
medioId: 5, symbol: "$", newValidFrom: newVf, activeValidFrom: activeVf);
|
||
|
|
|
||
|
|
ex.MedioId.Should().Be(5);
|
||
|
|
ex.Symbol.Should().Be("$");
|
||
|
|
ex.NewValidFrom.Should().Be(newVf);
|
||
|
|
ex.ActiveValidFrom.Should().Be(activeVf);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void ChargeableCharConfigForwardOnlyException_NullMedioId_IsAllowed()
|
||
|
|
{
|
||
|
|
var ex = new ChargeableCharConfigForwardOnlyException(
|
||
|
|
medioId: null, symbol: "$",
|
||
|
|
newValidFrom: new DateOnly(2026, 3, 1),
|
||
|
|
activeValidFrom: new DateOnly(2026, 4, 1));
|
||
|
|
|
||
|
|
ex.MedioId.Should().BeNull();
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void ChargeableCharConfigForwardOnlyException_MessageContainsKeyDates()
|
||
|
|
{
|
||
|
|
var newVf = new DateOnly(2026, 3, 1);
|
||
|
|
var activeVf = new DateOnly(2026, 4, 1);
|
||
|
|
|
||
|
|
var ex = new ChargeableCharConfigForwardOnlyException(
|
||
|
|
medioId: null, symbol: "$", newValidFrom: newVf, activeValidFrom: activeVf);
|
||
|
|
|
||
|
|
ex.Message.Should().Contain("2026-03-01");
|
||
|
|
ex.Message.Should().Contain("2026-04-01");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void ChargeableCharConfigForwardOnlyException_InheritsFromDomainException()
|
||
|
|
{
|
||
|
|
var ex = new ChargeableCharConfigForwardOnlyException(
|
||
|
|
medioId: null, symbol: "$",
|
||
|
|
newValidFrom: new DateOnly(2026, 3, 1),
|
||
|
|
activeValidFrom: new DateOnly(2026, 4, 1));
|
||
|
|
|
||
|
|
ex.Should().BeAssignableTo<DomainException>();
|
||
|
|
}
|
||
|
|
}
|