budget/BudgetApp.Tests/Domain/LedgerEntryTests.cs
2026-01-03 10:29:03 -06:00

149 lines
3.9 KiB
C#

namespace BudgetApp.Tests.Domain;
using BudgetApp.Domain.Models;
using Xunit;
public class LedgerEntryTests
{
[Fact]
public void Constructor_WithValidExpense_CreatesEntry()
{
// Arrange
var budgetAllocations = new Dictionary<Guid, Money>
{
{ Guid.NewGuid(), new Money(100m, "USD") }
};
// Act
var entry = new LedgerEntry(
DateTime.Now,
"Grocery Shopping",
new Money(100m, "USD"),
EntryType.Expense,
budgetAllocations);
// Assert
Assert.Equal("Grocery Shopping", entry.Description);
Assert.Equal(100m, entry.Amount.Amount);
Assert.Equal(EntryType.Expense, entry.Type);
Assert.Single(entry.BudgetAllocations);
}
[Fact]
public void Constructor_WithValidIncome_CreatesEntry()
{
// Arrange
var budgetAllocations = new Dictionary<Guid, Money>
{
{ Guid.NewGuid(), new Money(1000m, "USD") }
};
// Act
var entry = new LedgerEntry(
DateTime.Now,
"Salary",
new Money(1000m, "USD"),
EntryType.Income,
budgetAllocations);
// Assert
Assert.Equal("Salary", entry.Description);
Assert.Equal(1000m, entry.Amount.Amount);
Assert.Equal(EntryType.Income, entry.Type);
}
[Fact]
public void Validate_WithExpenseAllocationsNotMatchingAmount_ThrowsException()
{
// Arrange
var budgetAllocations = new Dictionary<Guid, Money>
{
{ Guid.NewGuid(), new Money(50m, "USD") }
};
// Act & Assert
Assert.Throws<InvalidOperationException>(() => new LedgerEntry(
DateTime.Now,
"Grocery Shopping",
new Money(100m, "USD"),
EntryType.Expense,
budgetAllocations));
}
[Fact]
public void Validate_WithIncomeAllocationsNotMatchingAmount_ThrowsException()
{
// Arrange
var budgetAllocations = new Dictionary<Guid, Money>
{
{ Guid.NewGuid(), new Money(500m, "USD") }
};
// Act & Assert
Assert.Throws<InvalidOperationException>(() => new LedgerEntry(
DateTime.Now,
"Salary",
new Money(1000m, "USD"),
EntryType.Income,
budgetAllocations));
}
[Fact]
public void Validate_WithMultipleBudgetAllocationsSummingToAmount_IsValid()
{
// Arrange
var budgetAllocations = new Dictionary<Guid, Money>
{
{ Guid.NewGuid(), new Money(90m, "USD") },
{ Guid.NewGuid(), new Money(10m, "USD") }
};
// Act
var entry = new LedgerEntry(
DateTime.Now,
"Grocery Shopping",
new Money(100m, "USD"),
EntryType.Expense,
budgetAllocations);
// Assert
Assert.Equal(2, entry.BudgetAllocations.Count);
Assert.Equal(100m, entry.Amount.Amount);
}
[Fact]
public void Validate_WithEmptyBudgetAllocations_ThrowsException()
{
// Arrange
var budgetAllocations = new Dictionary<Guid, Money>();
// Act & Assert
Assert.Throws<InvalidOperationException>(() => new LedgerEntry(
DateTime.Now,
"Grocery Shopping",
new Money(100m, "USD"),
EntryType.Expense,
budgetAllocations));
}
[Fact]
public void Validate_WithNullDescription_ThrowsException()
{
// Arrange
var budgetAllocations = new Dictionary<Guid, Money>
{
{ Guid.NewGuid(), new Money(100m, "USD") }
};
// Act & Assert
Assert.Throws<ArgumentException>(() => new LedgerEntry(
DateTime.Now,
null!,
new Money(100m, "USD"),
EntryType.Expense,
budgetAllocations));
}
}