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.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.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.NewGuid(), new Money(50m, "USD") } }; // Act & Assert Assert.Throws(() => 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.NewGuid(), new Money(500m, "USD") } }; // Act & Assert Assert.Throws(() => new LedgerEntry( DateTime.Now, "Salary", new Money(1000m, "USD"), EntryType.Income, budgetAllocations)); } [Fact] public void Validate_WithMultipleBudgetAllocationsSummingToAmount_IsValid() { // Arrange var budgetAllocations = new Dictionary { { 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(); // Act & Assert Assert.Throws(() => 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.NewGuid(), new Money(100m, "USD") } }; // Act & Assert Assert.Throws(() => new LedgerEntry( DateTime.Now, null!, new Money(100m, "USD"), EntryType.Expense, budgetAllocations)); } }