AyCode.Core/AyCode.Services.Tests/Nav/EkaerTradeCardValidatorTest...

189 lines
7.3 KiB
C#

using System.ComponentModel.DataAnnotations;
using AyCode.Services.Nav.Ekaer;
using AyCode.Services.Nav.Ekaer.Models;
using TradeReasonType = AyCode.Services.Nav.Ekaer.Models.Common.TradeReasonType;
using TradeType = AyCode.Services.Nav.Ekaer.Models.Common.TradeType;
namespace AyCode.Services.Tests.Nav;
/// <summary>
/// Unit tesztek az <see cref="EkaerTradeCardValidator"/>-ra: séma-szintű (generált DataAnnotations) és
/// üzleti szabályok (vonó jármű, tétel, feladó/címzett) ellenőrzése, hibalista-jelleggel. A validátor
/// általános NAV/EKÁER réteg — a teszt csak az AyCode.Services-re támaszkodik (semmi projekt-specifikus).
/// </summary>
[TestClass]
public sealed class EkaerTradeCardValidatorTests
{
private static readonly EkaerTradeCardValidator Sut = new();
// ---- Helpers ------------------------------------------------------------
/// <summary>Teljesen érvényes Create művelet, egy érvényes tétellel. A tesztek ezt „rontják el".</summary>
private static TradeCardOperationType ValidOperation()
{
var operation = new TradeCardOperationType
{
Index = 1,
Operation = OperationType.Create,
TradeCard = new TradeCardType
{
TradeType = TradeType.I,
SellerName = "Beszállító Kft",
SellerVatNumber = "12345678-2-42",
SellerCountry = "HU",
SellerAddress = "1011 Budapest Fo utca 1",
DestinationName = "FruitBank Kft",
DestinationVatNumber = "98765432-2-41",
DestinationCountry = "HU",
DestinationAddress = "1102 Budapest Raktar utca 5",
Vehicle = new BasicVehicleDetailType { PlateNumber = "ABC123", Country = "HU" },
},
};
operation.TradeCard.Items.Add(new TradeCardItemType
{
ItemExternalId = "1",
TradeReason = TradeReasonType.A,
ProductVtsz = "08081010",
ProductName = "Alma",
Weight = 123.5m,
});
return operation;
}
private static bool HasError(IReadOnlyList<ValidationResult> errors, string fragment)
=> errors.Any(e => e.ErrorMessage?.Contains(fragment, StringComparison.OrdinalIgnoreCase) == true);
// ---- Érvényes eset ------------------------------------------------------
[TestMethod]
public void Validate_ValidOperation_NoErrors()
{
var errors = Sut.Validate(ValidOperation());
Assert.AreEqual(0, errors.Count, $"érvényes művelet nem adhat hibát; kapott: {string.Join(" | ", errors.Select(e => e.ErrorMessage))}");
}
// ---- Üzleti szabályok ---------------------------------------------------
[TestMethod]
public void Validate_MissingVehicle_ReportsError()
{
var op = ValidOperation();
op.TradeCard!.Vehicle = null;
Assert.IsTrue(HasError(Sut.Validate(op), "vehicle"), "a hiányzó vonó jármű hibát ad");
}
[TestMethod]
public void Validate_NoItems_ReportsError()
{
var op = ValidOperation();
op.TradeCard!.Items.Clear();
Assert.IsTrue(HasError(Sut.Validate(op), "tétel"), "a tétel nélküli tradeCard hibát ad");
}
[TestMethod]
public void Validate_MissingSellerName_ReportsError()
{
var op = ValidOperation();
op.TradeCard!.SellerName = null;
Assert.IsTrue(HasError(Sut.Validate(op), "feladó"), "hiányzó feladónév → hiba");
}
[TestMethod]
public void Validate_MissingDestinationName_ReportsError()
{
var op = ValidOperation();
op.TradeCard!.DestinationName = " ";
Assert.IsTrue(HasError(Sut.Validate(op), "címzett"), "üres/whitespace címzettnév → hiba");
}
// ---- Séma-szint (generált DataAnnotations) ------------------------------
[TestMethod]
public void Validate_InvalidVtszPattern_ReportsError()
{
var op = ValidOperation();
op.TradeCard!.Items[0].ProductVtsz = "12"; // pattern [0-9]{4,8} → túl rövid
Assert.IsTrue(HasError(Sut.Validate(op), "productVtsz"), "rossz VTSZ-formátum → séma hiba");
}
[TestMethod]
public void Validate_NullVtsz_ReportsError()
{
var op = ValidOperation();
op.TradeCard!.Items[0].ProductVtsz = null; // a Required kapja el
Assert.IsTrue(HasError(Sut.Validate(op), "productVtsz"), "null VTSZ → Required hiba");
}
[TestMethod]
public void Validate_EmptyVtsz_ReportsError()
{
var op = ValidOperation();
op.TradeCard!.Items[0].ProductVtsz = ""; // a séma átengedné — az üzleti szabály kapja el
Assert.IsTrue(HasError(Sut.Validate(op), "productVtsz"), "üres VTSZ → üzleti szabály hiba");
}
[TestMethod]
public void Validate_InvalidPlateNumber_ReportsError()
{
var op = ValidOperation();
op.TradeCard!.Vehicle!.PlateNumber = "AB"; // MinLength 4 / pattern sérül
var errors = Sut.Validate(op);
Assert.IsTrue(HasError(errors, "plateNumber") || HasError(errors, "vehicle"), "túl rövid rendszám → séma hiba");
}
[TestMethod]
public void Validate_MissingProductName_ReportsError()
{
var op = ValidOperation();
op.TradeCard!.Items[0].ProductName = null; // [Required(AllowEmptyStrings=false)]
Assert.IsTrue(HasError(Sut.Validate(op), "productName"), "hiányzó terméknév → séma hiba");
}
// ---- Lista / művelet-szint ----------------------------------------------
[TestMethod]
public void Validate_EmptyList_ReportsError()
{
var errors = Sut.Validate(new List<TradeCardOperationType>());
Assert.IsTrue(HasError(errors, "legalább egy"), "üres lista → hiba");
}
[TestMethod]
public void Validate_DeleteWithoutTradeCard_DoesNotRequireTradeCard()
{
var op = new TradeCardOperationType { Index = 1, Operation = OperationType.Delete, Tcn = "ABC123" };
Assert.IsFalse(HasError(Sut.Validate(op), "a tradeCard kötelező"), "delete + Tcn esetén a tradeCard hiánya nem hiba");
}
[TestMethod]
public void Validate_NonDeleteWithoutTradeCard_ReportsError()
{
var op = new TradeCardOperationType { Index = 1, Operation = OperationType.Create, TradeCard = null };
Assert.IsTrue(HasError(Sut.Validate(op), "tradeCard"), "create esetén a tradeCard kötelező");
}
// ---- Hibalista-jelleg: minden hibát összegyűjt --------------------------
[TestMethod]
public void Validate_CollectsAllErrors_DoesNotStopAtFirst()
{
var op = ValidOperation();
op.TradeCard!.Vehicle = null; // üzleti
op.TradeCard.Items.Clear(); // üzleti
op.TradeCard.SellerName = null; // üzleti
op.TradeCard.DestinationVatNumber = null; // üzleti
var errors = Sut.Validate(op);
Assert.IsTrue(errors.Count >= 4, $"minden hibát összegyűjt, nem áll meg az elsőnél; kapott {errors.Count}");
}
[TestMethod]
public void Validate_IndexedPath_WhenMultipleOperations()
{
var bad = ValidOperation();
bad.TradeCard!.Vehicle = null;
var errors = Sut.Validate([ValidOperation(), bad]);
Assert.IsTrue(errors.Any(e => e.ErrorMessage?.Contains("[1]") == true), "a hibák a művelet indexével prefixeltek");
}
}