mirror of
https://github.com/Govor-team/Govor.git
synced 2026-07-21 19:54:55 +00:00
Media Controller Tests and other
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Text;
|
||||||
using AutoFixture;
|
using AutoFixture;
|
||||||
using Govor.API.Controllers;
|
using Govor.API.Controllers;
|
||||||
using Govor.Application.Interfaces.Infrastructure.Extensions;
|
using Govor.Application.Interfaces.Infrastructure.Extensions;
|
||||||
@@ -43,7 +44,7 @@ public class MediaControllerTests
|
|||||||
_currentUserMock.Object);
|
_currentUserMock.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for Upload action
|
// Tests for Upload action
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Upload_ValidRequest_ReturnsOkResult()
|
public async Task Upload_ValidRequest_ReturnsOkResult()
|
||||||
{
|
{
|
||||||
@@ -86,6 +87,272 @@ public class MediaControllerTests
|
|||||||
Assert.That(value.MediaId, Is.EqualTo(uploadResult.MediaId));
|
Assert.That(value.MediaId, Is.EqualTo(uploadResult.MediaId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Upload_InvalidModelState_ReturnsBadRequest()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
_controller.ModelState.AddModelError("Error", "Invalid model state");
|
||||||
|
var content = "fake file content";
|
||||||
|
var fileName = "testfile.txt";
|
||||||
|
var fileBytes = System.Text.Encoding.UTF8.GetBytes(content);
|
||||||
|
var stream = new MemoryStream(fileBytes);
|
||||||
|
|
||||||
|
var formFileMock = new Mock<IFormFile>();
|
||||||
|
formFileMock.Setup(f => f.Length).Returns(fileBytes.Length);
|
||||||
|
formFileMock.Setup(f => f.FileName).Returns(fileName);
|
||||||
|
formFileMock.Setup(f => f.OpenReadStream()).Returns(stream);
|
||||||
|
formFileMock.Setup(f => f.CopyToAsync(It.IsAny<Stream>(), default))
|
||||||
|
.Returns<Stream, CancellationToken>((target, _) => stream.CopyToAsync(target));
|
||||||
|
|
||||||
|
var uploadRequest = _fixture.Build<MediaUploadRequest>()
|
||||||
|
.With(r => r.FromFile, formFileMock.Object)
|
||||||
|
.With(r => r.Type, MediaType.Image)
|
||||||
|
.With(r => r.MimeType, "image/png")
|
||||||
|
.With(r => r.EncryptedKey, "secret")
|
||||||
|
.Create();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Upload(uploadRequest);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<BadRequestObjectResult>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Upload_NoFileUploaded_ReturnsBadRequest()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var uploadRequest = _fixture.Build<MediaUploadRequest>()
|
||||||
|
.With(r => r.FromFile, (IFormFile)null)
|
||||||
|
.Create();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Upload(uploadRequest);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<BadRequestObjectResult>());
|
||||||
|
var badRequestResult = result as BadRequestObjectResult;
|
||||||
|
Assert.That(badRequestResult?.Value, Is.EqualTo("No file uploaded"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Upload_EmptyFile_ReturnsBadRequest()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var formFileMock = new Mock<IFormFile>();
|
||||||
|
formFileMock.Setup(f => f.Length).Returns(0);
|
||||||
|
|
||||||
|
var uploadRequest = _fixture.Build<MediaUploadRequest>()
|
||||||
|
.With(r => r.FromFile, formFileMock.Object)
|
||||||
|
.Create();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Upload(uploadRequest);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<BadRequestObjectResult>());
|
||||||
|
var badRequestResult = result as BadRequestObjectResult;
|
||||||
|
Assert.That(badRequestResult?.Value, Is.EqualTo("No file uploaded"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Upload_FileTooLarge_ReturnsBadRequest()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var formFileMock = new Mock<IFormFile>();
|
||||||
|
formFileMock.Setup(f => f.Length).Returns(20_000_001); // Just over 20MB
|
||||||
|
|
||||||
|
var uploadRequest = _fixture.Build<MediaUploadRequest>()
|
||||||
|
.With(r => r.FromFile, formFileMock.Object)
|
||||||
|
.Create();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Upload(uploadRequest);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<BadRequestObjectResult>());
|
||||||
|
var badRequestResult = result as BadRequestObjectResult;
|
||||||
|
Assert.That(badRequestResult?.Value, Is.EqualTo("File is too large"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Upload_MissingMimeType_ReturnsBadRequest()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var formFileMock = new Mock<IFormFile>();
|
||||||
|
formFileMock.Setup(f => f.Length).Returns(1000);
|
||||||
|
formFileMock.Setup(f => f.FileName).Returns("testfile.txt");
|
||||||
|
|
||||||
|
var uploadRequest = _fixture.Build<MediaUploadRequest>()
|
||||||
|
.With(r => r.FromFile, formFileMock.Object)
|
||||||
|
.With(r => r.MimeType, string.Empty)
|
||||||
|
.Create();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Upload(uploadRequest);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<BadRequestObjectResult>());
|
||||||
|
var badRequestResult = result as BadRequestObjectResult;
|
||||||
|
Assert.That(badRequestResult?.Value, Is.EqualTo("Missing MIME type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Upload_UnauthorizedAccess_ReturnsUnauthorized()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var formFileMock = new Mock<IFormFile>();
|
||||||
|
formFileMock.Setup(f => f.Length).Returns(1000);
|
||||||
|
formFileMock.Setup(f => f.FileName).Returns("testfile.txt");
|
||||||
|
formFileMock.Setup(f => f.OpenReadStream()).Returns(new MemoryStream(new byte[1000]));
|
||||||
|
|
||||||
|
var uploadRequest = _fixture.Build<MediaUploadRequest>()
|
||||||
|
.With(r => r.FromFile, formFileMock.Object)
|
||||||
|
.With(r => r.MimeType, "text/plain")
|
||||||
|
.Create();
|
||||||
|
|
||||||
|
_mockMedia.Setup(f => f.UploadMediaAsync(It.IsAny<Media>()))
|
||||||
|
.ThrowsAsync(new UnauthorizedAccessException("Access denied"));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Upload(uploadRequest);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<UnauthorizedObjectResult>());
|
||||||
|
var unauthorizedResult = result as UnauthorizedObjectResult;
|
||||||
|
Assert.That(unauthorizedResult?.Value, Is.EqualTo("Access denied"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Upload_InvalidOperation_ReturnsBadRequest()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var formFileMock = new Mock<IFormFile>();
|
||||||
|
formFileMock.Setup(f => f.Length).Returns(1000);
|
||||||
|
formFileMock.Setup(f => f.FileName).Returns("testfile.txt");
|
||||||
|
formFileMock.Setup(f => f.OpenReadStream()).Returns(new MemoryStream(new byte[1000]));
|
||||||
|
|
||||||
|
var uploadRequest = _fixture.Build<MediaUploadRequest>()
|
||||||
|
.With(r => r.FromFile, formFileMock.Object)
|
||||||
|
.With(r => r.MimeType, "text/plain")
|
||||||
|
.Create();
|
||||||
|
|
||||||
|
_mockMedia.Setup(f => f.UploadMediaAsync(It.IsAny<Media>()))
|
||||||
|
.ThrowsAsync(new InvalidOperationException("Invalid operation"));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Upload(uploadRequest);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<BadRequestObjectResult>());
|
||||||
|
var badRequestResult = result as BadRequestObjectResult;
|
||||||
|
Assert.That(badRequestResult?.Value, Is.EqualTo("Invalid operation"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Upload_GeneralException_ReturnsInternalServerError()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var formFileMock = new Mock<IFormFile>();
|
||||||
|
formFileMock.Setup(f => f.Length).Returns(1000);
|
||||||
|
formFileMock.Setup(f => f.FileName).Returns("testfile.txt");
|
||||||
|
formFileMock.Setup(f => f.OpenReadStream()).Returns(new MemoryStream(new byte[1000]));
|
||||||
|
|
||||||
|
var uploadRequest = _fixture.Build<MediaUploadRequest>()
|
||||||
|
.With(r => r.FromFile, formFileMock.Object)
|
||||||
|
.With(r => r.MimeType, "text/plain")
|
||||||
|
.Create();
|
||||||
|
|
||||||
|
_mockMedia.Setup(f => f.UploadMediaAsync(It.IsAny<Media>()))
|
||||||
|
.ThrowsAsync(new Exception("Something went wrong"));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Upload(uploadRequest);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<ObjectResult>());
|
||||||
|
var objectResult = result as ObjectResult;
|
||||||
|
Assert.That(objectResult.StatusCode, Is.EqualTo(500));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests for Download action
|
||||||
|
[Test]
|
||||||
|
public async Task Download_HasAccessAndMediaExists_ReturnsFile()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var mediaId = Guid.NewGuid();
|
||||||
|
var media = _fixture.Build<Media>()
|
||||||
|
.With(m => m.Data, Encoding.UTF8.GetBytes("fake file content"))
|
||||||
|
.With(m => m.MimeType, "application/octet-stream") // Ensure MimeType is set
|
||||||
|
.With(m => m.FileName, "testfile.txt")
|
||||||
|
.Create();
|
||||||
|
|
||||||
|
_mockAccesser.Setup(f => f.HasAccessAsync(mediaId, _userId)).ReturnsAsync(true);
|
||||||
|
_mockMedia.Setup(f => f.GetMediaByIdAsync(mediaId)).ReturnsAsync(media);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Download(mediaId);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<FileContentResult>());
|
||||||
|
var fileResult = result as FileContentResult;
|
||||||
|
Assert.That(fileResult?.FileContents, Is.EqualTo(media.Data));
|
||||||
|
Assert.That(fileResult?.ContentType, Is.EqualTo(media.MimeType)); // Changed MineType to MimeType
|
||||||
|
Assert.That(fileResult?.FileDownloadName, Is.EqualTo(Path.GetFileName(media.FileName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Download_NoAccess_ReturnsForbid()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var mediaId = Guid.NewGuid();
|
||||||
|
|
||||||
|
_mockAccesser.Setup(f => f.HasAccessAsync(mediaId, _userId)).ReturnsAsync(false);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Download(mediaId);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<ForbidResult>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Download_MediaNotFound_ReturnsNotFound()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var mediaId = Guid.NewGuid();
|
||||||
|
|
||||||
|
_mockAccesser.Setup(f => f.HasAccessAsync(mediaId, _userId)).ReturnsAsync(true);
|
||||||
|
_mockMedia.Setup(f => f.GetMediaByIdAsync(mediaId))
|
||||||
|
.ThrowsAsync(new KeyNotFoundException("Media not found"));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Download(mediaId);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<NotFoundObjectResult>());
|
||||||
|
var notFoundResult = result as NotFoundObjectResult;
|
||||||
|
Assert.That(notFoundResult?.Value, Is.EqualTo("Media not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Download_GeneralException_ReturnsInternalServerError()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var mediaId = Guid.NewGuid();
|
||||||
|
|
||||||
|
_mockAccesser.Setup(f => f.HasAccessAsync(mediaId, _userId)).ReturnsAsync(true);
|
||||||
|
_mockMedia.Setup(f => f.GetMediaByIdAsync(mediaId))
|
||||||
|
.ThrowsAsync(new Exception("Something went wrong"));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _controller.Download(mediaId);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<ObjectResult>());
|
||||||
|
var objectResult = result as ObjectResult;
|
||||||
|
Assert.That(objectResult.StatusCode, Is.EqualTo(500));
|
||||||
|
}
|
||||||
|
|
||||||
[TearDown]
|
[TearDown]
|
||||||
public void TearDown()
|
public void TearDown()
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ public class MediaController : Controller
|
|||||||
|
|
||||||
var media = await _mediaService.GetMediaByIdAsync(id);
|
var media = await _mediaService.GetMediaByIdAsync(id);
|
||||||
|
|
||||||
return File(media.Data, media.MineType, Path.GetFileName(media.FileName));
|
return File(media.Data, media.MimeType, Path.GetFileName(media.FileName));
|
||||||
}
|
}
|
||||||
catch (KeyNotFoundException ex)
|
catch (KeyNotFoundException ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,16 +30,16 @@ public class ChatsHub : Hub
|
|||||||
if (userId == Guid.Empty)
|
if (userId == Guid.Empty)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("User connected with invalid UserID claim.");
|
_logger.LogWarning("User connected with invalid UserID claim.");
|
||||||
Context.Abort(); // Abort connection if userID is invalid
|
Context.Abort();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add user to their own group (for private messages and notifications)
|
|
||||||
await Groups.AddToGroupAsync(Context.ConnectionId, userId.ToString());
|
await Groups.AddToGroupAsync(Context.ConnectionId, userId.ToString());
|
||||||
_logger.LogInformation("User {UserId} connected with ConnectionId {ConnectionId} and added to their group",
|
_logger.LogInformation("User {UserId} connected with ConnectionId {ConnectionId} and added to their group",
|
||||||
userId, Context.ConnectionId);
|
userId, Context.ConnectionId);
|
||||||
|
|
||||||
var userGroups = await _userService.GetUserGroupsAsync(userId);
|
var userGroups = await _userService.GetUserGroupsAsync(userId);
|
||||||
|
|
||||||
foreach (var group in userGroups)
|
foreach (var group in userGroups)
|
||||||
{
|
{
|
||||||
await Groups.AddToGroupAsync(Context.ConnectionId, $"group_{group.Id}");
|
await Groups.AddToGroupAsync(Context.ConnectionId, $"group_{group.Id}");
|
||||||
@@ -51,19 +51,17 @@ public class ChatsHub : Hub
|
|||||||
public override async Task OnDisconnectedAsync(Exception? exception)
|
public override async Task OnDisconnectedAsync(Exception? exception)
|
||||||
{
|
{
|
||||||
var userId =
|
var userId =
|
||||||
GetUserId(suppressException: true); // Suppress exception if userID is not found (e.g. connection aborted early)
|
GetUserId(suppressException: true);
|
||||||
if (userId != Guid.Empty)
|
if (userId != Guid.Empty)
|
||||||
{
|
{
|
||||||
// Remove user from their own group
|
|
||||||
await Groups.RemoveFromGroupAsync(Context.ConnectionId, userId.ToString());
|
await Groups.RemoveFromGroupAsync(Context.ConnectionId, userId.ToString());
|
||||||
_logger.LogInformation(
|
_logger.LogInformation("User {UserId} disconnected with ConnectionId {ConnectionId} and removed from their group",
|
||||||
"User {UserId} disconnected with ConnectionId {ConnectionId} and removed from their group", userId,
|
userId, Context.ConnectionId);
|
||||||
Context.ConnectionId);
|
|
||||||
|
|
||||||
var userGroups =
|
var userGroups =
|
||||||
await _userService
|
await _userService
|
||||||
.GetUserGroupsAsync(
|
.GetUserGroupsAsync(
|
||||||
userId); // This might be problematic if the service relies on the user being connected
|
userId);
|
||||||
foreach (var group in userGroups)
|
foreach (var group in userGroups)
|
||||||
{
|
{
|
||||||
await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"group_{group.Id}");
|
await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"group_{group.Id}");
|
||||||
|
|||||||
@@ -33,11 +33,10 @@ public class FriendsHub : Hub
|
|||||||
if (userId == Guid.Empty)
|
if (userId == Guid.Empty)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("User connected with invalid UserID claim.");
|
_logger.LogWarning("User connected with invalid UserID claim.");
|
||||||
Context.Abort(); // Abort connection if userID is invalid
|
Context.Abort();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add user to their own group (for private messages and notifications)
|
|
||||||
await Groups.AddToGroupAsync(Context.ConnectionId, userId.ToString());
|
await Groups.AddToGroupAsync(Context.ConnectionId, userId.ToString());
|
||||||
_logger.LogInformation("User {UserId} connected with ConnectionId {ConnectionId} and added to their group",
|
_logger.LogInformation("User {UserId} connected with ConnectionId {ConnectionId} and added to their group",
|
||||||
userId, Context.ConnectionId);
|
userId, Context.ConnectionId);
|
||||||
@@ -48,7 +47,7 @@ public class FriendsHub : Hub
|
|||||||
public override async Task OnDisconnectedAsync(Exception? exception)
|
public override async Task OnDisconnectedAsync(Exception? exception)
|
||||||
{
|
{
|
||||||
var userId =
|
var userId =
|
||||||
GetUserId(suppressException: true); // Suppress exception if userID is not found (e.g. connection aborted early)
|
GetUserId(suppressException: true);
|
||||||
if (userId != Guid.Empty)
|
if (userId != Guid.Empty)
|
||||||
{
|
{
|
||||||
// Remove user from their own group
|
// Remove user from their own group
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public record Media(Guid UploaderId,
|
|||||||
string FileName,
|
string FileName,
|
||||||
byte[] Data,
|
byte[] Data,
|
||||||
MediaType Type,
|
MediaType Type,
|
||||||
string MineType,
|
string MimeType,
|
||||||
string EncryptedKey);
|
string EncryptedKey);
|
||||||
|
|
||||||
public record MediaUploadResult(Guid? MediaId, string Url);
|
public record MediaUploadResult(Guid? MediaId, string Url);
|
||||||
@@ -15,7 +15,7 @@ public interface IMessageCommandService
|
|||||||
// Task<Result> MarkMessageAsReadAsync(Guid userId, Guid messageId);
|
// Task<Result> MarkMessageAsReadAsync(Guid userId, Guid messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define specific result types for clarity, including original message for notifications if needed
|
|
||||||
|
|
||||||
public record SendMessageResult(bool IsSuccess, Exception? Exception, Message Message)
|
public record SendMessageResult(bool IsSuccess, Exception? Exception, Message Message)
|
||||||
: Result(IsSuccess, Exception, Message?.Id ?? Guid.Empty);
|
: Result(IsSuccess, Exception, Message?.Id ?? Guid.Empty);
|
||||||
@@ -23,7 +23,7 @@ public record SendMessageResult(bool IsSuccess, Exception? Exception, Message Me
|
|||||||
public record EditMessageResult(bool IsSuccess, Exception? Exception, Message? OriginalMessage)
|
public record EditMessageResult(bool IsSuccess, Exception? Exception, Message? OriginalMessage)
|
||||||
: Result(IsSuccess, Exception, OriginalMessage?.Id ?? Guid.Empty)
|
: Result(IsSuccess, Exception, OriginalMessage?.Id ?? Guid.Empty)
|
||||||
{
|
{
|
||||||
// OriginalMessage can be useful for the Hub to know details like RecipientType, RecipientId for notifications
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public record DeleteMessageResult(bool IsSuccess, Exception? Exception, Message? OriginalMessage)
|
public record DeleteMessageResult(bool IsSuccess, Exception? Exception, Message? OriginalMessage)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class MediaService : IMediaService
|
|||||||
UploaderId = file.UploaderId,
|
UploaderId = file.UploaderId,
|
||||||
DateCreated = file.UploadedOn,
|
DateCreated = file.UploadedOn,
|
||||||
MediaType = file.Type,
|
MediaType = file.Type,
|
||||||
MineType = file.MineType,
|
MineType = file.MimeType,
|
||||||
Url = url
|
Url = url
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ namespace Govor.Application.Services.Messages;
|
|||||||
public class MessageCommandService : IMessageCommandService
|
public class MessageCommandService : IMessageCommandService
|
||||||
{
|
{
|
||||||
private readonly IMessagesRepository _messagesRepository;
|
private readonly IMessagesRepository _messagesRepository;
|
||||||
private readonly IUsersRepository _usersRepository; // For validating user recipients
|
private readonly IUsersRepository _usersRepository;
|
||||||
private readonly IGroupsRepository _groupsRepository; // For validating group recipients and fetching members
|
private readonly IGroupsRepository _groupsRepository;
|
||||||
private readonly IPrivateChatsRepository _privateChats;
|
private readonly IPrivateChatsRepository _privateChats;
|
||||||
private readonly IVerifyFriendship _verifyFriendship; // For private messages
|
private readonly IVerifyFriendship _verifyFriendship;
|
||||||
private readonly ILogger<MessageCommandService> _logger;
|
private readonly ILogger<MessageCommandService> _logger;
|
||||||
|
|
||||||
public MessageCommandService(
|
public MessageCommandService(
|
||||||
|
|||||||
Reference in New Issue
Block a user