mirror of
https://github.com/Sea-Haven-Industries/proposal-system.git
synced 2026-09-30 13:33:15 +00:00
130 lines
4.1 KiB
C#
130 lines
4.1 KiB
C#
|
|
using FluentAssertions;
|
||
|
|
using ProposalSystem.Application.DTOs;
|
||
|
|
using ProposalSystem.Application.Validators;
|
||
|
|
using ProposalSystem.Domain.Entities;
|
||
|
|
using Xunit;
|
||
|
|
|
||
|
|
namespace ProposalSystem.Tests.Validators;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Tests for CreateLineItemValidator — validates line item payloads.
|
||
|
|
/// </summary>
|
||
|
|
public class CreateLineItemValidatorTests
|
||
|
|
{
|
||
|
|
private readonly CreateLineItemValidator _sut = new();
|
||
|
|
|
||
|
|
[Fact(DisplayName = "Valid line item request passes validation")]
|
||
|
|
public void ValidRequest_Passes()
|
||
|
|
{
|
||
|
|
var request = new CreateLineItemRequest(
|
||
|
|
Description: "HVAC duct replacement",
|
||
|
|
Quantity: 10,
|
||
|
|
Unit: "linear ft",
|
||
|
|
UnitPrice: 25.50m,
|
||
|
|
TotalPrice: 255.00m,
|
||
|
|
PricingMode: PricingMode.UnitPrice,
|
||
|
|
SortOrder: 1,
|
||
|
|
Source: LineItemSource.Manual
|
||
|
|
);
|
||
|
|
|
||
|
|
var result = _sut.Validate(request);
|
||
|
|
|
||
|
|
result.IsValid.Should().BeTrue();
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact(DisplayName = "Empty description fails")]
|
||
|
|
public void EmptyDescription_Fails()
|
||
|
|
{
|
||
|
|
var request = new CreateLineItemRequest("", 1, "each", null, 100m,
|
||
|
|
PricingMode.TotalPrice, 1, LineItemSource.Manual);
|
||
|
|
|
||
|
|
var result = _sut.Validate(request);
|
||
|
|
|
||
|
|
result.IsValid.Should().BeFalse();
|
||
|
|
result.Errors.Should().Contain(e => e.PropertyName == "Description");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact(DisplayName = "Zero quantity fails")]
|
||
|
|
public void ZeroQuantity_Fails()
|
||
|
|
{
|
||
|
|
var request = new CreateLineItemRequest("Work item", 0, "each", null, 100m,
|
||
|
|
PricingMode.TotalPrice, 1, LineItemSource.Manual);
|
||
|
|
|
||
|
|
var result = _sut.Validate(request);
|
||
|
|
|
||
|
|
result.IsValid.Should().BeFalse();
|
||
|
|
result.Errors.Should().Contain(e => e.PropertyName == "Quantity");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact(DisplayName = "Negative quantity fails")]
|
||
|
|
public void NegativeQuantity_Fails()
|
||
|
|
{
|
||
|
|
var request = new CreateLineItemRequest("Work item", -5, "each", null, 100m,
|
||
|
|
PricingMode.TotalPrice, 1, LineItemSource.Manual);
|
||
|
|
|
||
|
|
var result = _sut.Validate(request);
|
||
|
|
|
||
|
|
result.IsValid.Should().BeFalse();
|
||
|
|
result.Errors.Should().Contain(e => e.PropertyName == "Quantity");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact(DisplayName = "Negative total price fails")]
|
||
|
|
public void NegativeTotalPrice_Fails()
|
||
|
|
{
|
||
|
|
var request = new CreateLineItemRequest("Work item", 1, "each", null, -100m,
|
||
|
|
PricingMode.TotalPrice, 1, LineItemSource.Manual);
|
||
|
|
|
||
|
|
var result = _sut.Validate(request);
|
||
|
|
|
||
|
|
result.IsValid.Should().BeFalse();
|
||
|
|
result.Errors.Should().Contain(e => e.PropertyName == "TotalPrice");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact(DisplayName = "Negative unit price fails")]
|
||
|
|
public void NegativeUnitPrice_Fails()
|
||
|
|
{
|
||
|
|
var request = new CreateLineItemRequest("Work item", 1, "each", -10m, 100m,
|
||
|
|
PricingMode.UnitPrice, 1, LineItemSource.Manual);
|
||
|
|
|
||
|
|
var result = _sut.Validate(request);
|
||
|
|
|
||
|
|
result.IsValid.Should().BeFalse();
|
||
|
|
result.Errors.Should().Contain(e => e.PropertyName == "UnitPrice");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact(DisplayName = "Null unit price is valid (lump sum pricing)")]
|
||
|
|
public void NullUnitPrice_Passes()
|
||
|
|
{
|
||
|
|
var request = new CreateLineItemRequest("Work item", 1, "each", null, 100m,
|
||
|
|
PricingMode.TotalPrice, 1, LineItemSource.Manual);
|
||
|
|
|
||
|
|
var result = _sut.Validate(request);
|
||
|
|
|
||
|
|
result.IsValid.Should().BeTrue();
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact(DisplayName = "Empty unit fails")]
|
||
|
|
public void EmptyUnit_Fails()
|
||
|
|
{
|
||
|
|
var request = new CreateLineItemRequest("Work item", 1, "", null, 100m,
|
||
|
|
PricingMode.TotalPrice, 1, LineItemSource.Manual);
|
||
|
|
|
||
|
|
var result = _sut.Validate(request);
|
||
|
|
|
||
|
|
result.IsValid.Should().BeFalse();
|
||
|
|
result.Errors.Should().Contain(e => e.PropertyName == "Unit");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact(DisplayName = "Negative sort order fails")]
|
||
|
|
public void NegativeSortOrder_Fails()
|
||
|
|
{
|
||
|
|
var request = new CreateLineItemRequest("Work item", 1, "each", null, 100m,
|
||
|
|
PricingMode.TotalPrice, -1, LineItemSource.Manual);
|
||
|
|
|
||
|
|
var result = _sut.Validate(request);
|
||
|
|
|
||
|
|
result.IsValid.Should().BeFalse();
|
||
|
|
result.Errors.Should().Contain(e => e.PropertyName == "SortOrder");
|
||
|
|
}
|
||
|
|
}
|