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

159 lines
4.4 KiB
C#

namespace BudgetApp.Tests.Domain;
using BudgetApp.Domain.Models;
using Xunit;
public class GoalBudgetTests
{
[Fact]
public void Constructor_WithValidParameters_CreatesGoalBudget()
{
// Arrange & Act
var targetDate = DateTime.Now.AddYears(3);
var budget = new GoalBudget(
"Car Purchase",
new Money(0m, "USD"),
new Money(30000m, "USD"),
targetDate,
new Money(1000m, "USD"),
TimeSpan.FromDays(30));
// Assert
Assert.Equal("Car Purchase", budget.Name);
Assert.Equal(30000m, budget.GoalAmount.Amount);
Assert.Equal(targetDate, budget.TargetDate);
Assert.Equal(1000m, budget.PeriodicContribution.Amount);
}
[Fact]
public void Constructor_WithPastTargetDate_ThrowsException()
{
// Arrange, Act & Assert
var pastDate = DateTime.Now.AddDays(-1);
Assert.Throws<ArgumentException>(() => new GoalBudget(
"Test",
new Money(0m, "USD"),
new Money(10000m, "USD"),
pastDate,
new Money(1000m, "USD"),
TimeSpan.FromDays(30)));
}
[Fact]
public void Constructor_WithZeroGoalAmount_ThrowsException()
{
// Arrange, Act & Assert
var targetDate = DateTime.Now.AddYears(1);
Assert.Throws<ArgumentException>(() => new GoalBudget(
"Test",
new Money(0m, "USD"),
new Money(0m, "USD"),
targetDate,
new Money(1000m, "USD"),
TimeSpan.FromDays(30)));
}
[Fact]
public void IsGoalAchievable_WithSufficientContributions_ReturnsTrue()
{
// Arrange
var targetDate = DateTime.Now.AddYears(3);
var budget = new GoalBudget(
"Car Purchase",
new Money(0m, "USD"),
new Money(36000m, "USD"),
targetDate,
new Money(1000m, "USD"),
TimeSpan.FromDays(30));
// Act
var isAchievable = budget.IsGoalAchievable(DateTime.Now);
// Assert
Assert.True(isAchievable);
}
[Fact]
public void IsGoalAchievable_WithInsufficientContributions_ReturnsFalse()
{
// Arrange
var targetDate = DateTime.Now.AddMonths(1);
var budget = new GoalBudget(
"Car Purchase",
new Money(0m, "USD"),
new Money(100000m, "USD"),
targetDate,
new Money(1000m, "USD"),
TimeSpan.FromDays(30));
// Act
var isAchievable = budget.IsGoalAchievable(DateTime.Now);
// Assert
Assert.False(isAchievable);
}
[Fact]
public void CalculateRequiredContributionRate_WithSufficientTime_ReturnsCorrectRate()
{
// Arrange
var targetDate = DateTime.Now.AddYears(3);
var budget = new GoalBudget(
"Car Purchase",
new Money(0m, "USD"),
new Money(36000m, "USD"),
targetDate,
new Money(1000m, "USD"),
TimeSpan.FromDays(30));
// Act
var requiredRate = budget.CalculateRequiredContributionRate(DateTime.Now);
// Assert
Assert.True(requiredRate.Amount > 0);
Assert.True(requiredRate.Amount <= 1000m); // Should be achievable
}
[Fact]
public void CalculateRequiredContributionRate_WithCurrentBalanceAtGoal_ReturnsZero()
{
// Arrange
var targetDate = DateTime.Now.AddYears(1);
var budget = new GoalBudget(
"Car Purchase",
new Money(10000m, "USD"),
new Money(10000m, "USD"),
targetDate,
new Money(1000m, "USD"),
TimeSpan.FromDays(30));
// Act
var requiredRate = budget.CalculateRequiredContributionRate(DateTime.Now);
// Assert
Assert.Equal(0m, requiredRate.Amount);
}
[Fact]
public void IsGoalAchievable_WithBalanceExceedingGoal_ReturnsTrue()
{
// Arrange
var targetDate = DateTime.Now.AddYears(1);
var budget = new GoalBudget(
"Car Purchase",
new Money(15000m, "USD"),
new Money(10000m, "USD"),
targetDate,
new Money(1000m, "USD"),
TimeSpan.FromDays(30));
// Act
var isAchievable = budget.IsGoalAchievable(DateTime.Now);
// Assert
Assert.True(isAchievable);
}
}