mirror of
https://github.com/Govor-team/Govor.git
synced 2026-07-21 11:44:56 +00:00
b24649e53a
Reworked message loading endpoints and services to support flexible message querying with 'before' and 'after' parameters via a new MessageQuery contract. Updated controller actions, service interfaces, and implementations to use the new query model, and improved error handling. Added integration tests for ChatLoadController and introduced IUserPresenceService interface. Minor fixes and help text improvements in console client commands.
168 lines
5.6 KiB
C#
168 lines
5.6 KiB
C#
using Govor.Application.Interfaces;
|
|
using Govor.Application.Services.Messages;
|
|
using Govor.Core.Models;
|
|
using Govor.Core.Models.Messages;
|
|
using Govor.Core.Repositories.Groups;
|
|
using Govor.Core.Repositories.PrivateChats;
|
|
using Govor.Data;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Moq;
|
|
|
|
namespace Govor.Application.Tests.Services.Messages;
|
|
|
|
[TestFixture]
|
|
public class MessagesLoaderTests
|
|
{
|
|
private IMessagesLoader _loader;
|
|
private Mock<IPrivateChatsRepository> _privateChatsRepoMock;
|
|
private Mock<IGroupsRepository> _groupsRepoMock;
|
|
private GovorDbContext _dbContext;
|
|
|
|
private Guid _currentUserId = Guid.NewGuid();
|
|
private Guid _otherUserId = Guid.NewGuid();
|
|
private Guid _groupChatId = Guid.NewGuid();
|
|
|
|
[SetUp]
|
|
public void Setup()
|
|
{
|
|
_privateChatsRepoMock = new Mock<IPrivateChatsRepository>();
|
|
_groupsRepoMock = new Mock<IGroupsRepository>();
|
|
|
|
var options = new DbContextOptionsBuilder<GovorDbContext>()
|
|
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
|
|
.Options;
|
|
_dbContext = new GovorDbContext(options);
|
|
|
|
_loader = new MessagesLoader(_groupsRepoMock.Object, _privateChatsRepoMock.Object, _dbContext);
|
|
}
|
|
|
|
// Tests for LoadLastMessagesInUserChat action
|
|
[Test]
|
|
public async Task LoadLastMessagesInUserChat_ReturnsMessages_WhenChatExists()
|
|
{
|
|
// Arrange
|
|
var chatId = Guid.NewGuid();
|
|
|
|
_privateChatsRepoMock.Setup(r => r.Exist(_currentUserId, _otherUserId)).Returns(true);
|
|
_privateChatsRepoMock.Setup(r => r.GetByMembersAsync(_currentUserId, _otherUserId))
|
|
.ReturnsAsync(new PrivateChat() { Id = chatId });
|
|
|
|
var messages = new List<Message>
|
|
{
|
|
new() { Id = Guid.NewGuid(), RecipientId = chatId, RecipientType = RecipientType.User }
|
|
};
|
|
|
|
await _dbContext.Messages.AddRangeAsync(messages);
|
|
await _dbContext.SaveChangesAsync();
|
|
|
|
// Act
|
|
var result = await _loader.LoadMessagesInUserChat(_currentUserId, _otherUserId, null);
|
|
|
|
// Assert
|
|
Assert.That(result, Has.Count.EqualTo(1));
|
|
}
|
|
|
|
[Test]
|
|
public async Task LoadLastMessagesInUserChat_ReturnsEmpty_WhenNoMessages()
|
|
{
|
|
// Arrange
|
|
_privateChatsRepoMock.Setup(r => r.Exist(_currentUserId, _otherUserId)).Returns(true);
|
|
_privateChatsRepoMock.Setup(r => r.GetByMembersAsync(_currentUserId, _otherUserId))
|
|
.ReturnsAsync(new PrivateChat { Id = Guid.NewGuid() });
|
|
// Act
|
|
var result = await _loader.LoadMessagesInUserChat(_currentUserId, _otherUserId, null);
|
|
|
|
// Assert
|
|
Assert.That(result, Is.Empty);
|
|
}
|
|
|
|
[Test]
|
|
public void LoadLastMessagesInUserChat_Throws_WhenUserIdIsEmpty()
|
|
{
|
|
// Act & Assert
|
|
var ex = Assert.ThrowsAsync<ArgumentException>(async () =>
|
|
await _loader.LoadMessagesInUserChat(Guid.Empty, _currentUserId, null));
|
|
|
|
Assert.That(ex.Message, Does.Contain("User id cannot be empty"));
|
|
}
|
|
|
|
[Test]
|
|
public void LoadLastMessagesInUserChat_Throws_WhenChatNotExists()
|
|
{
|
|
// Arrange
|
|
_privateChatsRepoMock.Setup(r => r.Exist(It.IsAny<Guid>(), It.IsAny<Guid>())).Returns(false);
|
|
|
|
// Act & Assert
|
|
var ex = Assert.ThrowsAsync<InvalidOperationException>(async () =>
|
|
await _loader.LoadMessagesInUserChat(_currentUserId, _otherUserId, null));
|
|
|
|
Assert.That(ex.Message, Is.EqualTo("Private chat not found"));
|
|
}
|
|
|
|
// Tests for LoadLastMessagesInChatGroup action
|
|
[Test]
|
|
public async Task LoadLastMessagesInChatGroup_ReturnsMessages_WhenUserIsMember()
|
|
{
|
|
// Arrange
|
|
_groupsRepoMock.Setup(g => g.IsUserMemberOfGroupAsync(_currentUserId, _groupChatId))
|
|
.ReturnsAsync(true);
|
|
|
|
var messages = new List<Message>
|
|
{
|
|
new() { Id = Guid.NewGuid(), RecipientId = _groupChatId, RecipientType = RecipientType.Group }
|
|
};
|
|
|
|
await _dbContext.Messages.AddRangeAsync(messages);
|
|
await _dbContext.SaveChangesAsync();
|
|
|
|
// Act
|
|
var result = await _loader.LoadMessagesInChatGroup(_groupChatId, _currentUserId, null);
|
|
|
|
// Assert
|
|
Assert.That(result, Has.Count.EqualTo(1));
|
|
}
|
|
|
|
[Test]
|
|
public void LoadLastMessagesInChatGroup_Throws_WhenChatIdEmpty()
|
|
{
|
|
// Act & Assert
|
|
var ex = Assert.ThrowsAsync<ArgumentException>(async () =>
|
|
await _loader.LoadMessagesInChatGroup(Guid.Empty, _currentUserId, null));
|
|
|
|
Assert.That(ex.Message, Is.EqualTo("Chat id cannot be empty"));
|
|
}
|
|
|
|
[Test]
|
|
public void LoadLastMessagesInChatGroup_Throws_WhenUserNotInGroup()
|
|
{
|
|
// Arrange
|
|
_groupsRepoMock.Setup(g => g.IsUserMemberOfGroupAsync(_currentUserId, _groupChatId))
|
|
.ReturnsAsync(false);
|
|
|
|
// Act & Assert
|
|
var ex = Assert.ThrowsAsync<UnauthorizedAccessException>(async () =>
|
|
await _loader.LoadMessagesInChatGroup(_groupChatId, _currentUserId, null));
|
|
|
|
Assert.That(ex.Message, Is.EqualTo("You are not a member of this group."));
|
|
}
|
|
|
|
[Test]
|
|
public async Task LoadLastMessagesInChatGroup_ReturnsEmpty_WhenNoMessages()
|
|
{
|
|
// Arrange
|
|
_groupsRepoMock.Setup(g => g.IsUserMemberOfGroupAsync(_currentUserId, _groupChatId))
|
|
.ReturnsAsync(true);
|
|
|
|
// Act
|
|
var result = await _loader.LoadMessagesInChatGroup(_groupChatId, _currentUserId, null);
|
|
|
|
// Assert
|
|
Assert.That(result, Is.Empty);
|
|
}
|
|
|
|
[TearDown]
|
|
public void TearDown()
|
|
{
|
|
_dbContext.Dispose();
|
|
}
|
|
} |