diff --git a/Govor.API.Tests/UnitTests/Infrastructure/Validators/MessageValidatorTests.cs b/Govor.API.Tests/UnitTests/Infrastructure/Validators/MessageValidatorTests.cs new file mode 100644 index 0000000..32385ea --- /dev/null +++ b/Govor.API.Tests/UnitTests/Infrastructure/Validators/MessageValidatorTests.cs @@ -0,0 +1,7 @@ +namespace Govor.API.Tests.UnitTests.Infrastructure.Validators; + +[TestFixture] +public class MessageValidatorTests +{ + +} \ No newline at end of file diff --git a/Govor.API/Hubs/ChatsHub.cs b/Govor.API/Hubs/ChatsHub.cs index d1d9443..d8a9cee 100644 --- a/Govor.API/Hubs/ChatsHub.cs +++ b/Govor.API/Hubs/ChatsHub.cs @@ -42,6 +42,11 @@ public class ChatsHub : Hub } await base.OnDisconnectedAsync(exception); } + + public async Task Edit(string newMessage, Guid messageId) + { + + } public async Task Send(string message, Guid toUserId) { diff --git a/Govor.Core/Infrastructure/Validators/MessageValidator.cs b/Govor.Core/Infrastructure/Validators/MessageValidator.cs new file mode 100644 index 0000000..efa56bf --- /dev/null +++ b/Govor.Core/Infrastructure/Validators/MessageValidator.cs @@ -0,0 +1,44 @@ +using Govor.Core.Models; + +namespace Govor.Core.Infrastructure.Validators; + +public class MessageValidator : IObjectValidator +{ + public void Validate(Message message) + { + try + { + if (message is null) + throw new ArgumentNullException(nameof(message)); + if (message.Id == Guid.Empty) + throw new ArgumentException("Message ID cannot be empty", nameof(message.Id)); + if (message.SenderId == Guid.Empty) + throw new ArgumentException("Sender ID cannot be empty", nameof(message.SenderId)); + if (message.RecipientId == Guid.Empty) + throw new ArgumentException("Recipient ID cannot be empty", nameof(message.RecipientId)); + if(string.IsNullOrWhiteSpace(message.EncryptedContent)) + throw new ArgumentException("Encrypted content cannot be empty", nameof(message.EncryptedContent)); + if(message.IsEdited && message.EditedAt == DateTime.MinValue) + throw new ArgumentException("Edited at time cannot be empty", nameof(message.EditedAt)); + if (message.EditedAt == DateTime.MinValue) + throw new ArgumentException("Edited at time cannot be empty", nameof(message.EditedAt)); + } + catch (Exception ex) + { + throw new InvalidObjectException(ex); + } + } + + public bool TryValidate(Message message) + { + try + { + Validate(message); + return true; + } + catch (Exception ex) + { + return false; + } + } +} \ No newline at end of file diff --git a/Govor.Core/Models/Message.cs b/Govor.Core/Models/Message.cs new file mode 100644 index 0000000..9e1a20c --- /dev/null +++ b/Govor.Core/Models/Message.cs @@ -0,0 +1,19 @@ +namespace Govor.Core.Models; + +public class Message +{ + public Guid Id { get; set; } + public Guid SenderId { get; set; } + public Guid RecipientId { get; set; } // or GroupId + public RecipientType RecipientType { get; set; } + public string EncryptedContent { get; set; } = string.Empty; + public DateTime SentAt { get; set; } + public bool IsEdited { get; set; } = false; + public DateTime? EditedAt { get; set; } +} + +public enum RecipientType +{ + User, + Group +} \ No newline at end of file diff --git a/Govor.Core/Repositories/Messages/IMessagesExist.cs b/Govor.Core/Repositories/Messages/IMessagesExist.cs new file mode 100644 index 0000000..8fbcc96 --- /dev/null +++ b/Govor.Core/Repositories/Messages/IMessagesExist.cs @@ -0,0 +1,8 @@ +using Govor.Core.Models; + +namespace Govor.Core.Repositories.Messages; + +public interface IMessagesExist +{ + bool Exist(Message message); +} \ No newline at end of file diff --git a/Govor.Core/Repositories/Messages/IMessagesReader.cs b/Govor.Core/Repositories/Messages/IMessagesReader.cs new file mode 100644 index 0000000..a5f1abc --- /dev/null +++ b/Govor.Core/Repositories/Messages/IMessagesReader.cs @@ -0,0 +1,13 @@ +using Govor.Core.Models; + +namespace Govor.Core.Repositories.Messages; + +public interface IMessagesReader +{ + Task> GetAllAsync(); + Task FindByIdAsync(Guid messageId); + Task> FindBySenderIdAsync(Guid senderId); + Task> FindByReceiverIdAsync(Guid receiverId); + Task> FindBySenderAndReceiverIdAsync(Guid senderId, Guid receiverId); + Task> FindBySentAtAsync(DateTime date); +} \ No newline at end of file diff --git a/Govor.Core/Repositories/Messages/IMessagesRepository.cs b/Govor.Core/Repositories/Messages/IMessagesRepository.cs new file mode 100644 index 0000000..86867e9 --- /dev/null +++ b/Govor.Core/Repositories/Messages/IMessagesRepository.cs @@ -0,0 +1,6 @@ +namespace Govor.Core.Repositories.Messages; + +public interface IMessagesRepository : IMessagesReader, IMessagesWriter, IMessagesExist +{ + +} \ No newline at end of file diff --git a/Govor.Core/Repositories/Messages/IMessagesWriter.cs b/Govor.Core/Repositories/Messages/IMessagesWriter.cs new file mode 100644 index 0000000..bf4476e --- /dev/null +++ b/Govor.Core/Repositories/Messages/IMessagesWriter.cs @@ -0,0 +1,10 @@ +using Govor.Core.Models; + +namespace Govor.Core.Repositories.Messages; + +public interface IMessagesWriter +{ + void Add(Message message); + void Update(Message message); + void Delete(Guid messageId); +} \ No newline at end of file diff --git a/Govor.Data/GovorDbContext.cs b/Govor.Data/GovorDbContext.cs index 384b861..2e2f1ec 100644 --- a/Govor.Data/GovorDbContext.cs +++ b/Govor.Data/GovorDbContext.cs @@ -8,6 +8,7 @@ public class GovorDbContext(DbContextOptions options) : DbContex { public virtual DbSet Users { get; set; } public virtual DbSet ChatGroups { get; set; } + public virtual DbSet Messages { get; set; } public virtual DbSet GroupMemberships { get; set; } public virtual DbSet GroupAdmins { get; set; } } \ No newline at end of file diff --git a/Govor.Data/Repositories/MessagesRepository.cs b/Govor.Data/Repositories/MessagesRepository.cs new file mode 100644 index 0000000..2ed5ee0 --- /dev/null +++ b/Govor.Data/Repositories/MessagesRepository.cs @@ -0,0 +1,73 @@ +using Govor.Core.Infrastructure.Extensions; +using Govor.Core.Infrastructure.Validators; +using Govor.Core.Models; +using Govor.Core.Repositories.Messages; +using Govor.Data.Repositories.Exceptions; +using Microsoft.EntityFrameworkCore; + +namespace Govor.Data.Repositories; + +public class MessagesRepository : IMessagesRepository +{ + private GovorDbContext _context; + private IObjectValidator _validator; + + public MessagesRepository(GovorDbContext context, IObjectValidator validator) + { + _context = context; + _validator = validator; + } + + public async Task> GetAllAsync() + { + return await _context.Messages + .AsNoTracking() + .Where(x => true) + .ToListOrThrowIfEmpty(new NotFoundException("Messages in Database not exists")); + } + + public Task FindByIdAsync(Guid messageId) + { + throw new NotImplementedException(); + } + + public Task> FindBySenderIdAsync(Guid senderId) + { + throw new NotImplementedException(); + } + + public Task> FindByReceiverIdAsync(Guid receiverId) + { + throw new NotImplementedException(); + } + + public Task> FindBySenderAndReceiverIdAsync(Guid senderId, Guid receiverId) + { + throw new NotImplementedException(); + } + + public Task> FindBySentAtAsync(DateTime date) + { + throw new NotImplementedException(); + } + + public void Add(Message message) + { + throw new NotImplementedException(); + } + + public void Update(Message message) + { + throw new NotImplementedException(); + } + + public void Delete(Guid messageId) + { + throw new NotImplementedException(); + } + + public bool Exist(Message message) + { + throw new NotImplementedException(); + } +} \ No newline at end of file