// EN: Unit tests for PointAccount aggregate // VI: Unit tests cho PointAccount aggregate using WalletService.Domain.AggregatesModel.PointAccountAggregate; using WalletService.Domain.Exceptions; using Xunit; namespace WalletService.UnitTests.Domain; public class PointAccountTests { private static readonly Guid TestUserId = Guid.NewGuid(); [Fact] public void Constructor_ShouldCreatePointAccount_WithZeroBalance() { // Arrange & Act var account = new PointAccount(TestUserId); // Assert Assert.NotNull(account); Assert.Equal(TestUserId, account.UserId); Assert.Equal(0, account.TotalPoints); Assert.Equal(0, account.AvailablePoints); } [Fact] public void EarnPoints_ShouldIncreasePoints() { // Arrange var account = new PointAccount(TestUserId); var earnPoints = 100L; // Act account.EarnPoints(earnPoints, "ORDER001", "Test earn", null); // Assert Assert.Equal(earnPoints, account.TotalPoints); Assert.Equal(earnPoints, account.AvailablePoints); Assert.Single(account.Transactions); Assert.Equal(PointTransactionType.Earn, account.Transactions.First().Type); } [Fact] public void EarnPoints_ShouldThrow_WhenPointsAreNegative() { // Arrange var account = new PointAccount(TestUserId); // Act & Assert Assert.Throws(() => account.EarnPoints(-100, "ORDER001", "Invalid", null)); } [Fact] public void SpendPoints_ShouldDecreaseAvailablePoints() { // Arrange var account = new PointAccount(TestUserId); account.EarnPoints(100, "ORDER001", "Initial earn", null); // Act account.SpendPoints(50, "REWARD001", "Test spend"); // Assert Assert.Equal(100, account.TotalPoints); // Total remains same Assert.Equal(50, account.AvailablePoints); // Available decreases Assert.Equal(2, account.Transactions.Count); } [Fact] public void SpendPoints_ShouldThrow_WhenInsufficientPoints() { // Arrange var account = new PointAccount(TestUserId); account.EarnPoints(50, "ORDER001", "Initial earn", null); // Act & Assert Assert.Throws(() => account.SpendPoints(100, "REWARD001", "Invalid spend")); } [Fact] public void ExpirePoints_ShouldDecreaseAvailablePoints() { // Arrange var account = new PointAccount(TestUserId); account.EarnPoints(100, "ORDER001", "Initial earn", null); // Act account.ExpirePoints(30, "Points expired"); // Assert Assert.Equal(100, account.TotalPoints); // Total remains same Assert.Equal(70, account.AvailablePoints); // Available decreases } [Fact] public void AddBonusPoints_ShouldIncreasePoints() { // Arrange var account = new PointAccount(TestUserId); // Act account.AddBonusPoints(50, "PROMO001", "Bonus points", null); // Assert Assert.Equal(50, account.TotalPoints); Assert.Equal(50, account.AvailablePoints); Assert.Equal(PointTransactionType.Bonus, account.Transactions.First().Type); } [Fact] public void AdjustPoints_ShouldAdjustPositive() { // Arrange var account = new PointAccount(TestUserId); // Act account.AdjustPoints(100, "Admin adjustment"); // Assert Assert.Equal(100, account.TotalPoints); Assert.Equal(100, account.AvailablePoints); Assert.Equal(PointTransactionType.Adjust, account.Transactions.First().Type); } [Fact] public void AdjustPoints_ShouldAdjustNegative() { // Arrange var account = new PointAccount(TestUserId); account.EarnPoints(100, "ORDER001", "Initial earn", null); // Act account.AdjustPoints(-30, "Admin deduction"); // Assert Assert.Equal(100, account.TotalPoints); // Total doesn't decrease Assert.Equal(70, account.AvailablePoints); } [Fact] public void AdjustPoints_ShouldThrow_WhenInsufficientForNegativeAdjustment() { // Arrange var account = new PointAccount(TestUserId); account.EarnPoints(50, "ORDER001", "Initial earn", null); // Act & Assert Assert.Throws(() => account.AdjustPoints(-100, "Invalid deduction")); } }