mirror of
https://github.com/Govor-team/Govor.git
synced 2026-07-21 11:44:56 +00:00
FriendsController
This commit is contained in:
@@ -28,6 +28,7 @@ public class FriendshipValidatorTests
|
||||
[Test]
|
||||
public void Given_ValidFriendship_When_Validate_Then_Returns_True()
|
||||
{
|
||||
// Arrange
|
||||
var friendship = _fixture.Create<Friendship>();
|
||||
|
||||
// Act & Assert
|
||||
@@ -38,6 +39,7 @@ public class FriendshipValidatorTests
|
||||
[Test]
|
||||
public void Given_EmptyFriendshipId_When_Validate_Then_Returns_False()
|
||||
{
|
||||
// Arrange
|
||||
var friendship = _fixture.Create<Friendship>();
|
||||
friendship.Id = Guid.Empty;
|
||||
|
||||
@@ -49,6 +51,7 @@ public class FriendshipValidatorTests
|
||||
[Test]
|
||||
public void Given_EmptyRequesterId_When_Validate_Then_Returns_False()
|
||||
{
|
||||
// Arrange
|
||||
var friendship = _fixture.Create<Friendship>();
|
||||
friendship.RequesterId = Guid.Empty;
|
||||
|
||||
@@ -56,10 +59,23 @@ public class FriendshipValidatorTests
|
||||
Assert.Throws<InvalidObjectException<Friendship>>( () => _friendshipValidator.Validate(friendship));
|
||||
Assert.That(_friendshipValidator.TryValidate(friendship), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GivenSameRequesterId_When_Validate_Then_Returns_False()
|
||||
{
|
||||
// Arrange
|
||||
var friendship = _fixture.Create<Friendship>();
|
||||
friendship.RequesterId = friendship.AddresseeId;
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<InvalidObjectException<Friendship>>( () => _friendshipValidator.Validate(friendship));
|
||||
Assert.That(_friendshipValidator.TryValidate(friendship), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Given_AddresseeId_When_Validate_Then_Returns_False()
|
||||
{
|
||||
// Arrange
|
||||
var friendship = _fixture.Create<Friendship>();
|
||||
friendship.AddresseeId = Guid.Empty;
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
using Govor.Application.Exceptions.FriendsService;
|
||||
using Govor.Application.Interfaces;
|
||||
using Govor.Contracts.DTOs;
|
||||
using Govor.Core.Models;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
@@ -9,48 +13,151 @@ namespace Govor.API.Controllers;
|
||||
public class FriendsController : Controller
|
||||
{
|
||||
private readonly ILogger<FriendsController> _logger;
|
||||
private readonly IFriendsService _friendsService;
|
||||
|
||||
[HttpGet("search")]
|
||||
public async Task<IActionResult> Search([FromBody] string query)
|
||||
public FriendsController(ILogger<FriendsController> logger, IFriendsService friendsService)
|
||||
{
|
||||
return BadRequest("Not a valid request");
|
||||
_logger = logger;
|
||||
_friendsService = friendsService;
|
||||
}
|
||||
|
||||
[HttpGet("search")]
|
||||
public async Task<IActionResult> Search(string query)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _friendsService.SearchUsersAsync(query, GetCurrentUserId());
|
||||
|
||||
return Ok(BuildUserDtos(result));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, ex.Message);
|
||||
return BadRequest("Something happened during the search... try again");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("request")]
|
||||
public async Task<IActionResult> SendRequest([FromBody] Guid targetUserId)
|
||||
public async Task<IActionResult> SendRequest(Guid targetUserId)
|
||||
{
|
||||
return BadRequest("Not a valid request");
|
||||
try
|
||||
{
|
||||
await _friendsService.SendFriendRequestAsync(targetUserId, GetCurrentUserId());
|
||||
return Ok();
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogWarning("The user tried to send a friend request to themselves");
|
||||
return BadRequest("You can't send a friend request to themselves");
|
||||
}
|
||||
catch (RequestAlreadySentException ex)
|
||||
{
|
||||
_logger.LogWarning("The user tried to send a friend request but the request is already sent");
|
||||
return BadRequest("You already sent a friend request");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, ex.Message);
|
||||
return BadRequest("Something happened during the request... try again");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("requests")]
|
||||
public async Task<IActionResult> GetIncomingRequests()
|
||||
{
|
||||
return BadRequest("Not a valid request");
|
||||
try
|
||||
{
|
||||
_logger.LogInformation($"Getting incoming requests for user {GetCurrentUserId()}...");
|
||||
var result = await _friendsService.GetIncomingRequestsAsync(GetCurrentUserId());
|
||||
return Ok(BuildFriendshipDtos(result));
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogWarning(ex, ex.Message);
|
||||
return BadRequest("You can't get real friend requests because we can't find your user data! Try again");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("accept")]
|
||||
public async Task<IActionResult> AcceptFriend([FromBody] Guid requesterId)
|
||||
public async Task<IActionResult> AcceptFriend(Guid requesterId)
|
||||
{
|
||||
return BadRequest("Not a valid request");
|
||||
try
|
||||
{
|
||||
await _friendsService.AcceptFriendRequestAsync(requesterId, GetCurrentUserId());
|
||||
return Ok();
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogWarning("The user tried to accept a friend request but the request not exists");
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
_logger.LogWarning("User tried to accept a friend request but addresseeId not equal userId");
|
||||
return BadRequest("You can't accept a friend request");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetFriends()
|
||||
{
|
||||
return BadRequest("Not a valid request");
|
||||
try
|
||||
{
|
||||
_logger.LogInformation($"Getting friends by user {GetCurrentUserId()}...");
|
||||
var result = await _friendsService.GetFriendsAsync(GetCurrentUserId());
|
||||
|
||||
return Ok(BuildUserDtos(result));
|
||||
}
|
||||
catch(UnauthorizedAccessException ex)
|
||||
{
|
||||
_logger.LogError(ex, ex.Message);
|
||||
return BadRequest("Something happened during the request... try again");
|
||||
}
|
||||
}
|
||||
|
||||
private Guid GetCurrentUserId()
|
||||
{
|
||||
var userIdClaim = HttpContext.User?.FindFirst("userID")?.Value;
|
||||
_logger.LogInformation("Claims: {Claims}", string.Join(", ", HttpContext.User?.Claims.Select(c => $"{c.Type}: {c.Value}") ?? new string[0]));
|
||||
|
||||
if (string.IsNullOrEmpty(userIdClaim))
|
||||
if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
|
||||
{
|
||||
_logger.LogError("No userID claim found");
|
||||
return Guid.Empty;
|
||||
throw new UnauthorizedAccessException("userID claim is missing or invalid");
|
||||
}
|
||||
return userId;
|
||||
}
|
||||
|
||||
private List<UserDto> BuildUserDtos(IEnumerable<User> users)
|
||||
{
|
||||
List<UserDto> userDtos = new List<UserDto>();
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
userDtos.Add(new UserDto()
|
||||
{
|
||||
Id = user.Id,
|
||||
Description = user.Description,
|
||||
Username = user.Username,
|
||||
WasOnline = user.WasOnline,
|
||||
IconId = user.IconId,
|
||||
});
|
||||
}
|
||||
return userDtos;
|
||||
}
|
||||
|
||||
private List<FriendshipDto> BuildFriendshipDtos(List<Friendship> result)
|
||||
{
|
||||
List<FriendshipDto> dtos = new List<FriendshipDto>();
|
||||
|
||||
foreach (var friendship in result)
|
||||
{
|
||||
dtos.Add(new FriendshipDto()
|
||||
{
|
||||
Id = friendship.Id,
|
||||
Status = friendship.Status,
|
||||
AddresseeId = friendship.AddresseeId,
|
||||
RequesterId = friendship.RequesterId,
|
||||
});
|
||||
}
|
||||
|
||||
return Guid.TryParse(userIdClaim, out var userId) ? userId : Guid.Empty;
|
||||
return dtos;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ using Govor.Core.Infrastructure.Extensions;
|
||||
using Govor.Core.Infrastructure.Validators;
|
||||
using Govor.Core.Models;
|
||||
using Govor.Core.Repositories.Admins;
|
||||
using Govor.Core.Repositories.Friendships;
|
||||
using Govor.Core.Repositories.Invaites;
|
||||
using Govor.Core.Repositories.MediasAttachments;
|
||||
using Govor.Core.Repositories.Messages;
|
||||
@@ -30,6 +31,7 @@ public static class ConfigurationProgramExtensions
|
||||
services.AddScoped<IInvitesService, InvitesService>();
|
||||
services.AddScoped<IInvitationGenerator, InvitationGenerator>();
|
||||
services.AddScoped<IUsernameValidator, UsernameValidator>();
|
||||
services.AddScoped<IFriendsService, FriendsService>();
|
||||
|
||||
services.AddScoped<IStorageService>(sp =>
|
||||
{
|
||||
@@ -45,6 +47,7 @@ public static class ConfigurationProgramExtensions
|
||||
services.AddScoped<IInvitesRepository, InvitesRepository>();
|
||||
services.AddScoped<IAdminsRepository, AdminsRepository>();
|
||||
services.AddScoped<IMediaAttachmentsRepository, MediaAttachmentsRepository>();
|
||||
services.AddScoped<IFriendshipsRepository, FriendshipsRepository>();
|
||||
}
|
||||
|
||||
public static void AddValidators(this IServiceCollection services)
|
||||
@@ -54,6 +57,7 @@ public static class ConfigurationProgramExtensions
|
||||
services.AddScoped<IObjectValidator<MediaAttachments>, MediaAttachmentsValidator>();
|
||||
services.AddScoped<IObjectValidator<Admin>, AdminValidator>();
|
||||
services.AddScoped<IObjectValidator<Invitation>, InvitationValidator>();
|
||||
services.AddScoped<IObjectValidator<Friendship>, FriendshipValidator>();
|
||||
}
|
||||
|
||||
public static void AddGovorDbContext(this IServiceCollection services, IConfiguration configuration)
|
||||
|
||||
@@ -98,14 +98,10 @@ public class ChatsHub : Hub
|
||||
private Guid GetUserId()
|
||||
{
|
||||
var userIdClaim = Context.User?.FindFirst("userID")?.Value;
|
||||
_logger.LogInformation("Claims: {Claims}", string.Join(", ", Context.User?.Claims.Select(c => $"{c.Type}: {c.Value}") ?? new string[0]));
|
||||
|
||||
if (string.IsNullOrEmpty(userIdClaim))
|
||||
if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
|
||||
{
|
||||
_logger.LogError("No userID claim found");
|
||||
return Guid.Empty;
|
||||
throw new UnauthorizedAccessException("userID claim is missing or invalid");
|
||||
}
|
||||
|
||||
return Guid.TryParse(userIdClaim, out var userId) ? userId : Guid.Empty;
|
||||
return userId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
using Govor.Core;
|
||||
|
||||
namespace Govor.Application.Exceptions.FriendsService;
|
||||
|
||||
public class RequestAlreadySentException(Guid fromId, Guid userId)
|
||||
: GovorCoreException($"Request was already sent from {fromId} to {userId}") {}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Govor.Core;
|
||||
|
||||
namespace Govor.Application.Exceptions.FriendsService;
|
||||
|
||||
public class SearchUsersException : GovorCoreException
|
||||
{
|
||||
public SearchUsersException(string message, Exception innerException)
|
||||
: base(message, innerException){}
|
||||
|
||||
public SearchUsersException(string message)
|
||||
: base(message){}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
using Govor.Core;
|
||||
|
||||
namespace Govor.Application.Exceptions.FriendsService;
|
||||
|
||||
public class SendFriendRequestException(Guid fromUserId, Guid toUserId, Exception exception)
|
||||
: GovorCoreException($"Something happened when we try to send request from {fromUserId} to {toUserId}", exception);
|
||||
@@ -0,0 +1,12 @@
|
||||
using Govor.Core.Models;
|
||||
|
||||
namespace Govor.Application.Interfaces;
|
||||
|
||||
public interface IFriendsService
|
||||
{
|
||||
Task<List<User>> SearchUsersAsync(string searchTerm, Guid currentId);
|
||||
Task SendFriendRequestAsync(Guid fromUserId, Guid toUserId);
|
||||
Task AcceptFriendRequestAsync(Guid requestId, Guid currentUserId);
|
||||
Task<List<User>> GetFriendsAsync(Guid userId);
|
||||
Task<List<Friendship>> GetIncomingRequestsAsync(Guid userId);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
using Govor.Application.Exceptions;
|
||||
using Govor.Application.Exceptions.FriendsService;
|
||||
using Govor.Application.Interfaces;
|
||||
using Govor.Core.Models;
|
||||
using Govor.Core.Repositories.Friendships;
|
||||
using Govor.Core.Repositories.Users;
|
||||
using Govor.Data.Repositories.Exceptions;
|
||||
|
||||
namespace Govor.Application.Services;
|
||||
|
||||
public class FriendsService : IFriendsService
|
||||
{
|
||||
private IUsersRepository _usersRepository;
|
||||
private IFriendshipsRepository _friendshipsRepository;
|
||||
|
||||
public FriendsService(IUsersRepository usersRepository, IFriendshipsRepository relationshipsRepository)
|
||||
{
|
||||
_usersRepository = usersRepository;
|
||||
_friendshipsRepository = relationshipsRepository;
|
||||
}
|
||||
|
||||
public async Task<List<User>> SearchUsersAsync(string searchTerm, Guid currentId)
|
||||
{
|
||||
var all = await _usersRepository.SearchPotentialFriendsAsync(currentId, searchTerm);
|
||||
|
||||
try
|
||||
{
|
||||
var friends = await _friendshipsRepository.FindByUserIdAsync(currentId);
|
||||
|
||||
friends = friends.Where(f => f.Status == FriendshipStatus.Accepted).ToList();
|
||||
|
||||
return all
|
||||
.Where(u => u.Id != currentId && !friends.Select(f => f.RequesterId).Contains(u.Id))
|
||||
.ToList();
|
||||
}
|
||||
catch (NotFoundByKeyException<Guid> ex)
|
||||
{
|
||||
return all.Where(u => u.Id != currentId).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new SearchUsersException($"When we try find friends by pattern {searchTerm} something wrong", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SendFriendRequestAsync(Guid fromUserId, Guid toUserId)
|
||||
{
|
||||
if (fromUserId == toUserId)
|
||||
throw new InvalidOperationException("Cannot send a request to self user");
|
||||
|
||||
if (_friendshipsRepository.Exist(fromUserId, toUserId))
|
||||
throw new RequestAlreadySentException(fromUserId, toUserId);
|
||||
|
||||
await _friendshipsRepository.AddAsync(new Friendship()
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
RequesterId = fromUserId,
|
||||
AddresseeId = toUserId,
|
||||
Status = FriendshipStatus.Pending
|
||||
});
|
||||
}
|
||||
|
||||
public async Task AcceptFriendRequestAsync(Guid requestId, Guid currentUserId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var friendship = await _friendshipsRepository.GetByIdAsync(requestId);
|
||||
|
||||
if (friendship.AddresseeId != currentUserId)
|
||||
throw new UnauthorizedAccessException("You cannot accept this request");
|
||||
|
||||
if (friendship.Status != FriendshipStatus.Pending)
|
||||
throw new InvalidOperationException("Request is already accepted");
|
||||
|
||||
friendship.Status = FriendshipStatus.Accepted;
|
||||
await _friendshipsRepository.UpdateAsync(friendship);
|
||||
}
|
||||
catch (NotFoundByKeyException<Guid> e)
|
||||
{
|
||||
throw new InvalidOperationException("Friendship not found! You cant accept request!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<User>> GetFriendsAsync(Guid userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var user = await _usersRepository.FindByIdAsync(userId);
|
||||
|
||||
var sent = user.SentFriendRequests
|
||||
.Where(f => f.Status == FriendshipStatus.Accepted)
|
||||
.Select(f => f.Addressee);
|
||||
|
||||
var received = user.ReceivedFriendRequests
|
||||
.Where(f => f.Status == FriendshipStatus.Accepted)
|
||||
.Select(f => f.Requester);
|
||||
|
||||
return sent.Concat(received).ToList();
|
||||
}
|
||||
catch (NotFoundByKeyException<Guid> ex)
|
||||
{
|
||||
throw new InvalidOperationException("User not exist", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<Friendship>> GetIncomingRequestsAsync(Guid userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var user = await _usersRepository.FindByIdAsync(userId);
|
||||
return user.ReceivedFriendRequests;
|
||||
}
|
||||
catch (NotFoundByKeyException<Guid> ex)
|
||||
{
|
||||
throw new InvalidOperationException("User not exist", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using Govor.Core.Models;
|
||||
|
||||
namespace Govor.Contracts.DTOs;
|
||||
|
||||
public class FriendshipDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid RequesterId { get; set; }
|
||||
public Guid AddresseeId { get; set; }
|
||||
public FriendshipStatus Status { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Govor.Contracts.DTOs;
|
||||
|
||||
public class UserDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Description { get; set; }
|
||||
public DateTime WasOnline { get; set; }
|
||||
public Guid IconId {get; set;}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ public class FriendshipValidator : IObjectValidator<Friendship>
|
||||
throw new ArgumentException("Addresses cannot be empty", nameof(friendship.AddresseeId));
|
||||
if(friendship.RequesterId == Guid.Empty)
|
||||
throw new ArgumentException("Requester cannot be empty", nameof(friendship.RequesterId));
|
||||
if(friendship.AddresseeId == friendship.RequesterId)
|
||||
throw new ArgumentException("Addresses cannot be same", nameof(friendship.AddresseeId));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -9,5 +9,6 @@ public interface IUsersReader
|
||||
public Task<List<User>> FindByRangeIdAsync(IEnumerable<Guid> ids);
|
||||
public Task<User> FindByUsernameAsync(string username);
|
||||
public Task<List<User>> FindByRangeUsernamesAsync(IEnumerable<string> usernames);
|
||||
public Task<List<User>> SearchPotentialFriendsAsync(Guid currentUserId, string query);
|
||||
public Task<List<User>> FindUsersByCreatedDateAsync(DateOnly createdDate);
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Govor.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Govor.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(GovorDbContext))]
|
||||
[Migration("20250627101322_friendships")]
|
||||
partial class friendships
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.6")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Admin", b =>
|
||||
{
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("Admins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.ChatGroup", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.PrimitiveCollection<List<Guid>>("Admins")
|
||||
.IsRequired()
|
||||
.HasColumnType("uuid[]");
|
||||
|
||||
b.PrimitiveCollection<List<string>>("InviteCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<bool>("IsChannel")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsPrivate")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ChatGroups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Friendship", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("AddresseeId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("RequesterId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AddresseeId");
|
||||
|
||||
b.HasIndex("RequesterId");
|
||||
|
||||
b.ToTable("Friendships");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.GroupAdmins", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("GroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GroupAdmins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.GroupMembership", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("GroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsBanned")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GroupMemberships");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Invitation", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("DateCreated")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("EndDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAdmin")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("MaxParticipants")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Invitations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.MediaAttachments", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("EncryptedKey")
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("character varying(512)");
|
||||
|
||||
b.Property<string>("FilePath")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("MessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("MimeType")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MessageId");
|
||||
|
||||
b.ToTable("MediaAttachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Message", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("EditedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("EncryptedContent")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsEdited")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid?>("PrivateChatId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("RecipientId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("RecipientType")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid?>("ReplyToMessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("SenderId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("SentAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PrivateChatId");
|
||||
|
||||
b.HasIndex("ReplyToMessageId");
|
||||
|
||||
b.ToTable("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.MessageReaction", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("MessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("ReactedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("ReactionCode")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("MessageId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("MessageReactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.MessageView", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("MessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("ViewedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MessageId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("MessageViews");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.PrivateChat", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserAId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserBId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PrivateChats");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateOnly>("CreatedOn")
|
||||
.HasColumnType("date");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("IconId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("InviteId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("WasOnline")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InviteId");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Admin", b =>
|
||||
{
|
||||
b.HasOne("Govor.Core.Models.User", "User")
|
||||
.WithOne()
|
||||
.HasForeignKey("Govor.Core.Models.Admin", "UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Friendship", b =>
|
||||
{
|
||||
b.HasOne("Govor.Core.Models.User", "Addressee")
|
||||
.WithMany("ReceivedFriendRequests")
|
||||
.HasForeignKey("AddresseeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Core.Models.User", "Requester")
|
||||
.WithMany("SentFriendRequests")
|
||||
.HasForeignKey("RequesterId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Addressee");
|
||||
|
||||
b.Navigation("Requester");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.MediaAttachments", b =>
|
||||
{
|
||||
b.HasOne("Govor.Core.Models.Message", "Message")
|
||||
.WithMany("MediaAttachments")
|
||||
.HasForeignKey("MessageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Message");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Message", b =>
|
||||
{
|
||||
b.HasOne("Govor.Core.Models.PrivateChat", null)
|
||||
.WithMany("Messages")
|
||||
.HasForeignKey("PrivateChatId");
|
||||
|
||||
b.HasOne("Govor.Core.Models.Message", "ReplyToMessage")
|
||||
.WithMany()
|
||||
.HasForeignKey("ReplyToMessageId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.Navigation("ReplyToMessage");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.MessageReaction", b =>
|
||||
{
|
||||
b.HasOne("Govor.Core.Models.Message", "Message")
|
||||
.WithMany("Reactions")
|
||||
.HasForeignKey("MessageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Core.Models.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Message");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.MessageView", b =>
|
||||
{
|
||||
b.HasOne("Govor.Core.Models.Message", null)
|
||||
.WithMany("MessageViews")
|
||||
.HasForeignKey("MessageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.User", b =>
|
||||
{
|
||||
b.HasOne("Govor.Core.Models.Invitation", "Invite")
|
||||
.WithMany("Users")
|
||||
.HasForeignKey("InviteId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Invite");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Invitation", b =>
|
||||
{
|
||||
b.Navigation("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Message", b =>
|
||||
{
|
||||
b.Navigation("MediaAttachments");
|
||||
|
||||
b.Navigation("MessageViews");
|
||||
|
||||
b.Navigation("Reactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.PrivateChat", b =>
|
||||
{
|
||||
b.Navigation("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.User", b =>
|
||||
{
|
||||
b.Navigation("ReceivedFriendRequests");
|
||||
|
||||
b.Navigation("SentFriendRequests");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Govor.Data.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class friendships : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "PrivateChatId",
|
||||
table: "Messages",
|
||||
type: "uuid",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Friendships",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
RequesterId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
AddresseeId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Status = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Friendships", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Friendships_Users_AddresseeId",
|
||||
column: x => x.AddresseeId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Friendships_Users_RequesterId",
|
||||
column: x => x.RequesterId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PrivateChats",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserAId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserBId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PrivateChats", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Messages_PrivateChatId",
|
||||
table: "Messages",
|
||||
column: "PrivateChatId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Friendships_AddresseeId",
|
||||
table: "Friendships",
|
||||
column: "AddresseeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Friendships_RequesterId",
|
||||
table: "Friendships",
|
||||
column: "RequesterId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Messages_PrivateChats_PrivateChatId",
|
||||
table: "Messages",
|
||||
column: "PrivateChatId",
|
||||
principalTable: "PrivateChats",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Messages_PrivateChats_PrivateChatId",
|
||||
table: "Messages");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Friendships");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PrivateChats");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Messages_PrivateChatId",
|
||||
table: "Messages");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "PrivateChatId",
|
||||
table: "Messages");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,30 @@ namespace Govor.Data.Migrations
|
||||
b.ToTable("ChatGroups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Friendship", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("AddresseeId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("RequesterId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AddresseeId");
|
||||
|
||||
b.HasIndex("RequesterId");
|
||||
|
||||
b.ToTable("Friendships");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.GroupAdmins", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -181,6 +205,9 @@ namespace Govor.Data.Migrations
|
||||
b.Property<bool>("IsEdited")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid?>("PrivateChatId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("RecipientId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
@@ -198,6 +225,8 @@ namespace Govor.Data.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PrivateChatId");
|
||||
|
||||
b.HasIndex("ReplyToMessageId");
|
||||
|
||||
b.ToTable("Messages");
|
||||
@@ -256,6 +285,23 @@ namespace Govor.Data.Migrations
|
||||
b.ToTable("MessageViews");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.PrivateChat", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserAId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("UserBId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PrivateChats");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -304,6 +350,25 @@ namespace Govor.Data.Migrations
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Friendship", b =>
|
||||
{
|
||||
b.HasOne("Govor.Core.Models.User", "Addressee")
|
||||
.WithMany("ReceivedFriendRequests")
|
||||
.HasForeignKey("AddresseeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Govor.Core.Models.User", "Requester")
|
||||
.WithMany("SentFriendRequests")
|
||||
.HasForeignKey("RequesterId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Addressee");
|
||||
|
||||
b.Navigation("Requester");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.MediaAttachments", b =>
|
||||
{
|
||||
b.HasOne("Govor.Core.Models.Message", "Message")
|
||||
@@ -317,6 +382,10 @@ namespace Govor.Data.Migrations
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.Message", b =>
|
||||
{
|
||||
b.HasOne("Govor.Core.Models.PrivateChat", null)
|
||||
.WithMany("Messages")
|
||||
.HasForeignKey("PrivateChatId");
|
||||
|
||||
b.HasOne("Govor.Core.Models.Message", "ReplyToMessage")
|
||||
.WithMany()
|
||||
.HasForeignKey("ReplyToMessageId")
|
||||
@@ -377,6 +446,18 @@ namespace Govor.Data.Migrations
|
||||
|
||||
b.Navigation("Reactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.PrivateChat", b =>
|
||||
{
|
||||
b.Navigation("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Govor.Core.Models.User", b =>
|
||||
{
|
||||
b.Navigation("ReceivedFriendRequests");
|
||||
|
||||
b.Navigation("SentFriendRequests");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ public class UsersRepository : IUsersRepository
|
||||
{
|
||||
return await _context.Users
|
||||
.AsNoTracking()
|
||||
.Include(u => u.Invite)
|
||||
.Include(u => u.ReceivedFriendRequests)
|
||||
.Include(u => u.SentFriendRequests)
|
||||
.ToListOrThrowIfEmpty(new NotFoundException("Users in Database not exists"));
|
||||
}
|
||||
|
||||
@@ -33,6 +36,8 @@ public class UsersRepository : IUsersRepository
|
||||
return await _context.Users
|
||||
.AsNoTracking()
|
||||
.Include(u => u.Invite)
|
||||
.Include(u => u.ReceivedFriendRequests)
|
||||
.Include(u => u.SentFriendRequests)
|
||||
.FirstOrDefaultAsync(x => x.Id == id)
|
||||
?? throw new NotFoundByKeyException<Guid>(id, "User with given id does not exist");
|
||||
}
|
||||
@@ -46,6 +51,8 @@ public class UsersRepository : IUsersRepository
|
||||
.AsNoTracking()
|
||||
.Where(x => ids.Contains(x.Id))
|
||||
.Include(u => u.Invite)
|
||||
.Include(u => u.ReceivedFriendRequests)
|
||||
.Include(u => u.SentFriendRequests)
|
||||
.ToListOrThrowIfEmpty(new NotFoundByKeyException<IEnumerable<Guid>>(ids,"Users with given ids not found"));
|
||||
}
|
||||
|
||||
@@ -57,10 +64,30 @@ public class UsersRepository : IUsersRepository
|
||||
return await _context.Users
|
||||
.AsNoTracking()
|
||||
.Include(u => u.Invite)
|
||||
.Include(u => u.ReceivedFriendRequests)
|
||||
.Include(u => u.SentFriendRequests)
|
||||
.FirstOrDefaultAsync(x => x.Username == username)
|
||||
?? throw new NotFoundByKeyException<string>(username, "User with given username does not exist");
|
||||
}
|
||||
|
||||
public async Task<List<User>> SearchPotentialFriendsAsync(Guid currentUserId, string query)
|
||||
{
|
||||
return await _context.Users
|
||||
.AsNoTracking()
|
||||
.Include(u => u.Invite)
|
||||
.Include(u => u.ReceivedFriendRequests)
|
||||
.Include(u => u.SentFriendRequests)
|
||||
.Where(u => u.Id != currentUserId &&
|
||||
u.Username.ToLower().Contains(query.ToLower()) &&
|
||||
!_context.Friendships.Any(f =>
|
||||
(f.RequesterId == currentUserId && f.AddresseeId == u.Id) ||
|
||||
(f.RequesterId == u.Id && f.AddresseeId == currentUserId)))
|
||||
.Take(20)
|
||||
.OrderBy(u => u.Username)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
public async Task<List<User>> FindByRangeUsernamesAsync(IEnumerable<string> usernames)
|
||||
{
|
||||
if (usernames is null || !usernames.Any())
|
||||
@@ -70,6 +97,8 @@ public class UsersRepository : IUsersRepository
|
||||
.AsNoTracking()
|
||||
.Where(x => usernames.Contains(x.Username))
|
||||
.Include(u => u.Invite)
|
||||
.Include(u => u.ReceivedFriendRequests)
|
||||
.Include(u => u.SentFriendRequests)
|
||||
.ToListOrThrowIfEmpty(new NotFoundByKeyException<IEnumerable<string>>(usernames, "Users with given usernames not found"));
|
||||
}
|
||||
|
||||
@@ -82,6 +111,8 @@ public class UsersRepository : IUsersRepository
|
||||
.AsNoTracking()
|
||||
.Where(u => createdDate == u.CreatedOn)
|
||||
.Include(u => u.Invite)
|
||||
.Include(u => u.ReceivedFriendRequests)
|
||||
.Include(u => u.SentFriendRequests)
|
||||
.ToListOrThrowIfEmpty(new NotFoundByKeyException<DateOnly>(createdDate, "Users with given created date do not exist"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user