153 lines
5.0 KiB
C#
153 lines
5.0 KiB
C#
namespace BudgetApp.Tests.Domain;
|
|
|
|
using BudgetApp.Domain.Models;
|
|
using Xunit;
|
|
|
|
public class LedgerTests
|
|
{
|
|
[Fact]
|
|
public void Constructor_CreatesEmptyLedger()
|
|
{
|
|
// Arrange & Act
|
|
var ledger = new Ledger();
|
|
|
|
// Assert
|
|
Assert.Empty(ledger.Entries);
|
|
}
|
|
|
|
[Fact]
|
|
public void AddEntry_WithValidEntry_AddsToLedger()
|
|
{
|
|
// Arrange
|
|
var ledger = new Ledger();
|
|
var budgetAllocations = new Dictionary<Guid, Money>
|
|
{
|
|
{ Guid.NewGuid(), new Money(100m, "USD") }
|
|
};
|
|
var entry = new LedgerEntry(
|
|
DateTime.Now,
|
|
"Grocery Shopping",
|
|
new Money(100m, "USD"),
|
|
EntryType.Expense,
|
|
budgetAllocations);
|
|
|
|
// Act
|
|
ledger.AddEntry(entry);
|
|
|
|
// Assert
|
|
Assert.Single(ledger.Entries);
|
|
Assert.Equal(entry, ledger.Entries.First());
|
|
}
|
|
|
|
[Fact]
|
|
public void AddEntry_WithInvalidEntry_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var ledger = new Ledger();
|
|
var budgetAllocations = new Dictionary<Guid, Money>
|
|
{
|
|
{ Guid.NewGuid(), new Money(50m, "USD") }
|
|
};
|
|
|
|
// Act & Assert - The exception is thrown during construction, not when adding
|
|
Assert.Throws<InvalidOperationException>(() => new LedgerEntry(
|
|
Guid.NewGuid(),
|
|
DateTime.Now,
|
|
"Grocery Shopping",
|
|
new Money(100m, "USD"),
|
|
EntryType.Expense,
|
|
budgetAllocations));
|
|
}
|
|
|
|
[Fact]
|
|
public void GetEntriesByType_ReturnsOnlyMatchingType()
|
|
{
|
|
// Arrange
|
|
var ledger = new Ledger();
|
|
var expenseAllocations = new Dictionary<Guid, Money> { { Guid.NewGuid(), new Money(100m, "USD") } };
|
|
var incomeAllocations = new Dictionary<Guid, Money> { { Guid.NewGuid(), new Money(1000m, "USD") } };
|
|
|
|
var expense = new LedgerEntry(DateTime.Now, "Expense", new Money(100m, "USD"), EntryType.Expense, expenseAllocations);
|
|
var income = new LedgerEntry(DateTime.Now, "Income", new Money(1000m, "USD"), EntryType.Income, incomeAllocations);
|
|
|
|
ledger.AddEntry(expense);
|
|
ledger.AddEntry(income);
|
|
|
|
// Act
|
|
var expenses = ledger.GetEntriesByType(EntryType.Expense);
|
|
var incomes = ledger.GetEntriesByType(EntryType.Income);
|
|
|
|
// Assert
|
|
Assert.Single(expenses);
|
|
Assert.Single(incomes);
|
|
Assert.Equal(EntryType.Expense, expenses.First().Type);
|
|
Assert.Equal(EntryType.Income, incomes.First().Type);
|
|
}
|
|
|
|
[Fact]
|
|
public void CalculateTotalByType_ReturnsCorrectTotal()
|
|
{
|
|
// Arrange
|
|
var ledger = new Ledger();
|
|
var expenseAllocations1 = new Dictionary<Guid, Money> { { Guid.NewGuid(), new Money(100m, "USD") } };
|
|
var expenseAllocations2 = new Dictionary<Guid, Money> { { Guid.NewGuid(), new Money(200m, "USD") } };
|
|
|
|
var expense1 = new LedgerEntry(DateTime.Now, "Expense 1", new Money(100m, "USD"), EntryType.Expense, expenseAllocations1);
|
|
var expense2 = new LedgerEntry(DateTime.Now, "Expense 2", new Money(200m, "USD"), EntryType.Expense, expenseAllocations2);
|
|
|
|
ledger.AddEntry(expense1);
|
|
ledger.AddEntry(expense2);
|
|
|
|
// Act
|
|
var total = ledger.CalculateTotalByType(EntryType.Expense, "USD");
|
|
|
|
// Assert
|
|
Assert.Equal(300m, total.Amount);
|
|
}
|
|
|
|
[Fact]
|
|
public void CalculateNetBalance_ReturnsIncomeMinusExpenses()
|
|
{
|
|
// Arrange
|
|
var ledger = new Ledger();
|
|
var expenseAllocations = new Dictionary<Guid, Money> { { Guid.NewGuid(), new Money(100m, "USD") } };
|
|
var incomeAllocations = new Dictionary<Guid, Money> { { Guid.NewGuid(), new Money(1000m, "USD") } };
|
|
|
|
var expense = new LedgerEntry(DateTime.Now, "Expense", new Money(100m, "USD"), EntryType.Expense, expenseAllocations);
|
|
var income = new LedgerEntry(DateTime.Now, "Income", new Money(1000m, "USD"), EntryType.Income, incomeAllocations);
|
|
|
|
ledger.AddEntry(expense);
|
|
ledger.AddEntry(income);
|
|
|
|
// Act
|
|
var netBalance = ledger.CalculateNetBalance("USD");
|
|
|
|
// Assert
|
|
Assert.Equal(900m, netBalance.Amount);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetEntriesForBudget_ReturnsEntriesWithBudgetAllocation()
|
|
{
|
|
// Arrange
|
|
var budgetId = Guid.NewGuid();
|
|
var ledger = new Ledger();
|
|
var allocations1 = new Dictionary<Guid, Money> { { budgetId, new Money(100m, "USD") } };
|
|
var allocations2 = new Dictionary<Guid, Money> { { Guid.NewGuid(), new Money(200m, "USD") } };
|
|
|
|
var entry1 = new LedgerEntry(DateTime.Now, "Entry 1", new Money(100m, "USD"), EntryType.Expense, allocations1);
|
|
var entry2 = new LedgerEntry(DateTime.Now, "Entry 2", new Money(200m, "USD"), EntryType.Expense, allocations2);
|
|
|
|
ledger.AddEntry(entry1);
|
|
ledger.AddEntry(entry2);
|
|
|
|
// Act
|
|
var entries = ledger.GetEntriesForBudget(budgetId);
|
|
|
|
// Assert
|
|
Assert.Single(entries);
|
|
Assert.Equal(entry1, entries.First());
|
|
}
|
|
}
|
|
|