159 lines
4.4 KiB
C#
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);
|
|
}
|
|
}
|
|
|
|
|