215 lines
7.7 KiB
C#
215 lines
7.7 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using FluentAssertions;
|
|
using Microsoft.Extensions.Caching.Distributed;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Logging;
|
|
using Moq;
|
|
using TeleBot.Models;
|
|
using TeleBot.Services;
|
|
using Xunit;
|
|
|
|
namespace TeleBot.Tests.Services
|
|
{
|
|
public class SessionManagerTests
|
|
{
|
|
private readonly SessionManager _sessionManager;
|
|
private readonly Mock<IConfiguration> _mockConfiguration;
|
|
private readonly Mock<ILogger<SessionManager>> _mockLogger;
|
|
private readonly Mock<IPrivacyService> _mockPrivacyService;
|
|
private readonly Mock<IDistributedCache> _mockCache;
|
|
|
|
public SessionManagerTests()
|
|
{
|
|
_mockConfiguration = new Mock<IConfiguration>();
|
|
_mockLogger = new Mock<ILogger<SessionManager>>();
|
|
_mockPrivacyService = new Mock<IPrivacyService>();
|
|
_mockCache = new Mock<IDistributedCache>();
|
|
|
|
// Set up default configuration
|
|
_mockConfiguration.Setup(x => x["Privacy:SessionTimeoutMinutes"])
|
|
.Returns("30");
|
|
_mockConfiguration.Setup(x => x["Privacy:EphemeralByDefault"])
|
|
.Returns("true");
|
|
_mockConfiguration.Setup(x => x["Redis:Enabled"])
|
|
.Returns("false");
|
|
|
|
// Set up privacy service
|
|
_mockPrivacyService.Setup(x => x.HashIdentifier(It.IsAny<long>()))
|
|
.Returns<long>(id => $"HASH_{id}");
|
|
|
|
_sessionManager = new SessionManager(
|
|
_mockConfiguration.Object,
|
|
_mockLogger.Object,
|
|
_mockPrivacyService.Object,
|
|
null // No cache for unit tests
|
|
);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetOrCreateSessionAsync_NewUser_ShouldCreateSession()
|
|
{
|
|
// Arrange
|
|
long telegramUserId = 123456;
|
|
|
|
// Act
|
|
var session = await _sessionManager.GetOrCreateSessionAsync(telegramUserId);
|
|
|
|
// Assert
|
|
session.Should().NotBeNull();
|
|
session.HashedUserId.Should().Be($"HASH_{telegramUserId}");
|
|
session.IsEphemeral.Should().BeTrue();
|
|
session.State.Should().Be(SessionState.MainMenu);
|
|
session.Cart.Should().NotBeNull();
|
|
session.Cart.IsEmpty().Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetOrCreateSessionAsync_ExistingUser_ShouldReturnSameSession()
|
|
{
|
|
// Arrange
|
|
long telegramUserId = 123456;
|
|
|
|
// Act
|
|
var session1 = await _sessionManager.GetOrCreateSessionAsync(telegramUserId);
|
|
var session2 = await _sessionManager.GetOrCreateSessionAsync(telegramUserId);
|
|
|
|
// Assert
|
|
session1.Id.Should().Be(session2.Id);
|
|
session1.HashedUserId.Should().Be(session2.HashedUserId);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateSessionAsync_ShouldUpdateSession()
|
|
{
|
|
// Arrange
|
|
long telegramUserId = 123456;
|
|
var session = await _sessionManager.GetOrCreateSessionAsync(telegramUserId);
|
|
|
|
// Act
|
|
session.State = SessionState.BrowsingCategories;
|
|
session.Cart.AddItem(Guid.NewGuid(), "Test Product", 10.00m, 2);
|
|
await _sessionManager.UpdateSessionAsync(session);
|
|
|
|
var retrievedSession = await _sessionManager.GetOrCreateSessionAsync(telegramUserId);
|
|
|
|
// Assert
|
|
retrievedSession.State.Should().Be(SessionState.BrowsingCategories);
|
|
retrievedSession.Cart.GetTotalItems().Should().Be(2);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DeleteSessionAsync_ShouldRemoveSession()
|
|
{
|
|
// Arrange
|
|
long telegramUserId = 123456;
|
|
var session = await _sessionManager.GetOrCreateSessionAsync(telegramUserId);
|
|
var sessionId = session.Id;
|
|
|
|
// Act
|
|
await _sessionManager.DeleteSessionAsync(sessionId);
|
|
var newSession = await _sessionManager.GetOrCreateSessionAsync(telegramUserId);
|
|
|
|
// Assert
|
|
newSession.Id.Should().NotBe(sessionId, "Should create a new session after deletion");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DeleteUserDataAsync_ShouldRemoveAllUserSessions()
|
|
{
|
|
// Arrange
|
|
long telegramUserId = 123456;
|
|
var session = await _sessionManager.GetOrCreateSessionAsync(telegramUserId);
|
|
var originalSessionId = session.Id;
|
|
|
|
// Act
|
|
await _sessionManager.DeleteUserDataAsync(telegramUserId);
|
|
var newSession = await _sessionManager.GetOrCreateSessionAsync(telegramUserId);
|
|
|
|
// Assert
|
|
newSession.Id.Should().NotBe(originalSessionId);
|
|
newSession.Cart.IsEmpty().Should().BeTrue();
|
|
newSession.State.Should().Be(SessionState.MainMenu);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CleanupExpiredSessionsAsync_ShouldRemoveExpiredSessions()
|
|
{
|
|
// Arrange
|
|
long userId1 = 111111;
|
|
long userId2 = 222222;
|
|
|
|
var session1 = await _sessionManager.GetOrCreateSessionAsync(userId1);
|
|
session1.ExpiresAt = DateTime.UtcNow.AddMinutes(-1); // Expired
|
|
await _sessionManager.UpdateSessionAsync(session1);
|
|
|
|
var session2 = await _sessionManager.GetOrCreateSessionAsync(userId2);
|
|
// session2 not expired
|
|
|
|
// Act
|
|
await _sessionManager.CleanupExpiredSessionsAsync();
|
|
|
|
var retrievedSession1 = await _sessionManager.GetOrCreateSessionAsync(userId1);
|
|
var retrievedSession2 = await _sessionManager.GetOrCreateSessionAsync(userId2);
|
|
|
|
// Assert
|
|
retrievedSession1.Id.Should().NotBe(session1.Id, "Expired session should be recreated");
|
|
retrievedSession2.Id.Should().Be(session2.Id, "Non-expired session should remain");
|
|
}
|
|
|
|
[Fact]
|
|
public void Session_IsExpired_ShouldReturnCorrectStatus()
|
|
{
|
|
// Arrange
|
|
var expiredSession = new UserSession
|
|
{
|
|
ExpiresAt = DateTime.UtcNow.AddMinutes(-1)
|
|
};
|
|
|
|
var activeSession = new UserSession
|
|
{
|
|
ExpiresAt = DateTime.UtcNow.AddMinutes(30)
|
|
};
|
|
|
|
// Assert
|
|
expiredSession.IsExpired().Should().BeTrue();
|
|
activeSession.IsExpired().Should().BeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void Session_UpdateActivity_ShouldUpdateLastActivityTime()
|
|
{
|
|
// Arrange
|
|
var session = new UserSession();
|
|
var originalTime = session.LastActivityAt;
|
|
|
|
// Act
|
|
System.Threading.Thread.Sleep(10); // Small delay
|
|
session.UpdateActivity();
|
|
|
|
// Assert
|
|
session.LastActivityAt.Should().BeAfter(originalTime);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetOrCreateSessionAsync_WithPrivacySettings_ShouldApplyDefaults()
|
|
{
|
|
// Arrange
|
|
_mockConfiguration.Setup(x => x["Privacy:EphemeralByDefault"])
|
|
.Returns("true");
|
|
_mockConfiguration.Setup(x => x["Features:EnableDisappearingMessages"])
|
|
.Returns("true");
|
|
|
|
long telegramUserId = 999999;
|
|
|
|
// Act
|
|
var session = await _sessionManager.GetOrCreateSessionAsync(telegramUserId);
|
|
|
|
// Assert
|
|
session.Privacy.Should().NotBeNull();
|
|
session.Privacy.UseEphemeralMode.Should().BeTrue();
|
|
session.Privacy.DisableAnalytics.Should().BeTrue();
|
|
session.Privacy.EnableDisappearingMessages.Should().BeTrue();
|
|
}
|
|
}
|
|
} |