Files
pos-system/services/mission-service-net/tests/MissionService.UnitTests/Domain/UserCheckInAggregateTests.cs

199 lines
5.1 KiB
C#

namespace MissionService.UnitTests.Domain;
using FluentAssertions;
using MissionService.Domain.AggregatesModel.CheckInAggregate;
using Xunit;
/// <summary>
/// EN: Tests for UserCheckIn aggregate root invariants and behavior.
/// VI: Kiểm thử các quy tắc bất biến và hành vi của UserCheckIn aggregate root.
/// </summary>
public class UserCheckInAggregateTests
{
private readonly StreakBonusConfig _defaultConfig = StreakBonusConfig.Default();
#region Constructor Tests
[Fact]
public void Constructor_ValidUserId_CreatesCheckInWithZeroStreak()
{
// Arrange
var userId = Guid.NewGuid();
// Act
var checkIn = new UserCheckIn(userId);
// Assert
checkIn.UserId.Should().Be(userId);
checkIn.CurrentStreak.Should().Be(0);
checkIn.LongestStreak.Should().Be(0);
checkIn.TotalCheckIns.Should().Be(0);
checkIn.LastCheckInDate.Should().BeNull();
checkIn.CheckInDays.Should().BeEmpty();
}
[Fact]
public void Constructor_EmptyUserId_ThrowsArgumentException()
{
// Arrange & Act
var act = () => new UserCheckIn(Guid.Empty);
// Assert
act.Should().Throw<ArgumentException>()
.WithMessage("*User ID is required*");
}
#endregion
#region CanCheckInToday Tests
[Fact]
public void CanCheckInToday_NewUser_ReturnsTrue()
{
// Arrange
var checkIn = new UserCheckIn(Guid.NewGuid());
// Act
var result = checkIn.CanCheckInToday();
// Assert
result.Should().BeTrue();
}
[Fact]
public void CanCheckInToday_AfterCheckIn_ReturnsFalse()
{
// Arrange
var checkIn = new UserCheckIn(Guid.NewGuid());
checkIn.CheckIn(_defaultConfig);
// Act
var result = checkIn.CanCheckInToday();
// Assert
result.Should().BeFalse();
}
#endregion
#region CheckIn Tests
[Fact]
public void CheckIn_FirstTime_SetsStreakToOne()
{
// Arrange
var checkIn = new UserCheckIn(Guid.NewGuid());
// Act
var result = checkIn.CheckIn(_defaultConfig);
// Assert
checkIn.CurrentStreak.Should().Be(1);
checkIn.LongestStreak.Should().Be(1);
checkIn.TotalCheckIns.Should().Be(1);
result.CurrentStreak.Should().Be(1);
}
[Fact]
public void CheckIn_FirstTime_AwardsDailyPoints()
{
// Arrange
var checkIn = new UserCheckIn(Guid.NewGuid());
// Act
var result = checkIn.CheckIn(_defaultConfig);
// Assert
result.DailyPoints.Should().BeGreaterThan(0);
result.TotalPoints.Should().BeGreaterThanOrEqualTo(result.DailyPoints);
}
[Fact]
public void CheckIn_AlreadyCheckedInToday_ThrowsInvalidOperationException()
{
// Arrange
var checkIn = new UserCheckIn(Guid.NewGuid());
checkIn.CheckIn(_defaultConfig);
// Act
var act = () => checkIn.CheckIn(_defaultConfig);
// Assert
act.Should().Throw<InvalidOperationException>()
.WithMessage("*Already checked in today*");
}
[Fact]
public void CheckIn_AddsCheckInDayRecord()
{
// Arrange
var checkIn = new UserCheckIn(Guid.NewGuid());
// Act
var result = checkIn.CheckIn(_defaultConfig);
// Assert
checkIn.CheckInDays.Should().HaveCount(1);
var dayRecord = checkIn.CheckInDays.First();
dayRecord.PointsEarned.Should().Be(result.TotalPoints);
dayRecord.StreakOnDay.Should().Be(1);
}
#endregion
#region ResetStreak Tests
[Fact]
public void ResetStreak_WithActiveStreak_ResetsCurrentStreakToZero()
{
// Arrange
var checkIn = new UserCheckIn(Guid.NewGuid());
checkIn.CheckIn(_defaultConfig);
checkIn.CurrentStreak.Should().Be(1);
// Act
checkIn.ResetStreak();
// Assert
checkIn.CurrentStreak.Should().Be(0);
// EN: LongestStreak should remain unchanged
// VI: LongestStreak nên giữ nguyên
checkIn.LongestStreak.Should().Be(1);
}
#endregion
#region GetMonthlyCheckIns Tests
[Fact]
public void GetMonthlyCheckIns_NoCheckIns_ReturnsEmptyList()
{
// Arrange
var checkIn = new UserCheckIn(Guid.NewGuid());
var now = DateTime.UtcNow;
// Act
var result = checkIn.GetMonthlyCheckIns(now.Year, now.Month);
// Assert
result.Should().BeEmpty();
}
[Fact]
public void GetMonthlyCheckIns_WithCheckIns_ReturnsCurrentMonthCheckIns()
{
// Arrange
var checkIn = new UserCheckIn(Guid.NewGuid());
checkIn.CheckIn(_defaultConfig);
var now = DateTime.UtcNow;
// Act
var result = checkIn.GetMonthlyCheckIns(now.Year, now.Month);
// Assert
result.Should().HaveCount(1);
}
#endregion
}