using AutoFixture; using Govor.Core.Infrastructure.Validators; using Govor.Core.Models; using Govor.Data; using Govor.Data.Repositories; using Govor.Data.Repositories.Exceptions; using Microsoft.EntityFrameworkCore; namespace Govor.Data.Tests.Repositories; [TestFixture] public class UsersRepositoryTests { private Fixture _fixture; private DbContextOptions _options; private readonly IObjectValidator _userValidator = new UserValidator(); [SetUp] public void SetUp() { _fixture = new Fixture(); _fixture.Behaviors .OfType() .ToList() .ForEach(b => _fixture.Behaviors.Remove(b)); _fixture.Behaviors.Add(new OmitOnRecursionBehavior()); _options = new DbContextOptionsBuilder() .UseInMemoryDatabase(databaseName: "DbGovor") .Options; } [Test] public async Task GetAll_Then_Returns_All_Users() { // Arrange var random = new Random(); var users = _fixture.CreateMany(random.Next(2, 10)).ToList(); _options = new DbContextOptionsBuilder() .UseInMemoryDatabase(databaseName: "DbGovor_users_getall") .Options; await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); context.Users.AddRange(users); await context.SaveChangesAsync(); // Act var result = await userRepository.GetAllAsync(); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Count, Is.EqualTo(users.Count)); Assert.That(result.Select(u => u.Id), Is.EquivalentTo(users.Select(u => u.Id))); Assert.That(result.Select(u => u.Username), Is.EquivalentTo(users.Select(u => u.Username))); } [Test] public async Task Given_ValidUserId_When_FindById_Then_Returns_User() { // Arrange var user = _fixture.Create(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); context.Users.Add(user); await context.SaveChangesAsync(); // Act var result = await userRepository.FindByIdAsync(user.Id); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Username, Is.EqualTo(user.Username)); Assert.That(result.Id, Is.EqualTo(user.Id)); } [Test] public async Task Given_InvalidUserId_When_FindById_Should_Throw_NotFoundException() { // Arrange var id = Guid.NewGuid(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act & Assert Assert.ThrowsAsync>(async () => await userRepository.FindByIdAsync(id)); } [Test] public async Task Given_RangeValidUserId_When_FindByRangeId_Then_Returns_Users() { // Arrange var random = new Random(); var users = _fixture.CreateMany(random.Next(2, 10)).ToList(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); context.Users.AddRange(users); await context.SaveChangesAsync(); // Act var result = await userRepository.FindByRangeIdAsync(users.Select(u => u.Id)); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Count, Is.EqualTo(users.Count)); Assert.That(result.Select(r => r.Id), Is.EquivalentTo(users.Select(u => u.Id))); Assert.That(result.Select(u => u.Username), Is.EquivalentTo(users.Select(u => u.Username))); } [Test] public async Task Given_InvalidRangeId_When_FindByRangeId_Should_Throw_NotFoundException() { // Arrange var random = new Random(); var ids = _fixture.CreateMany(random.Next(2, 10)).ToList(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act & Assert Assert.ThrowsAsync>>(async () => await userRepository.FindByRangeIdAsync(ids)); } [Test] public async Task Given_ValidUsername_When_FindByUsername_Then_Returns_User() { // Arrange var user = _fixture.Create(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); context.Users.Add(user); await context.SaveChangesAsync(); // Act var result = await userRepository.FindByUsernameAsync(user.Username); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Username, Is.EqualTo(user.Username)); Assert.That(result.Id, Is.EqualTo(user.Id)); } [Test] public async Task Given_InvalidUsername_When_FindByUsername_Should_Throw_NotFoundByKeyException() { // Arrange string username = _fixture.Create(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act & Assert Assert.ThrowsAsync>(async () => await userRepository.FindByUsernameAsync(username)); } [Test] public async Task Given_ValidUsernames_When_FindByRangeUsernames_Then_Returns_Users() { // Arrange var random = new Random(); var users = _fixture.CreateMany(random.Next(3, 10)).ToList(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); context.Users.AddRange(users); await context.SaveChangesAsync(); // Act var result = await userRepository.FindByRangeUsernamesAsync(users.Select(u => u.Username)); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Select(u => u.Username), Is.EquivalentTo(users.Select(u => u.Username))); Assert.That(result.Select(u => u.Id), Is.EquivalentTo(users.Select(u => u.Id))); } [Test] public async Task Given_InvalidUsernames_When_FindByRangeUsernames_Should_Throw_NotFoundByKeyException() { // Arrange var random = new Random(); var usernames = _fixture.CreateMany(random.Next(3, 10)).ToList(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act & Assert Assert.ThrowsAsync>>(async () => await userRepository.FindByRangeUsernamesAsync(usernames)); } [Test] public async Task Given_ValidQuery_When_SearchPotentialFriendsAsync_Then_Returns_Users() { // Arrange var random = new Random(); var users = _fixture.CreateMany(random.Next(3, 10)).ToList(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); context.Users.AddRange(users); await context.SaveChangesAsync(); // Act var result = await userRepository.SearchPotentialFriendsAsync(users[1].Id, users[0].Username[..15]); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Count, Is.EqualTo(1)); Assert.That(result.First().Id, Is.EqualTo(users[0].Id)); } [Test] public async Task Given_InvalidQuery_When_SearchPotentialFriendsAsync_Should_Throw_NotFoundByKeyException() { // Arrange await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act & Assert Assert.ThrowsAsync>(async () => await userRepository.SearchPotentialFriendsAsync(_fixture.Create(), _fixture.Create())); } [Test] public async Task Given_ValidDateOnly_When_FindByCreatedDate_Then_Returns_Users() { // Arrange var random = new Random(); var users = _fixture.CreateMany(random.Next(3, 10)).ToList(); var selectedDate = users[random.Next(users.Count)].CreatedOn; await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); context.Users.AddRange(users); await context.SaveChangesAsync(); // Act var result = await userRepository.FindUsersByCreatedDateAsync(selectedDate); // Assert var expectedUsers = users .Where(u => u.CreatedOn == selectedDate) .ToList(); Assert.That(result, Is.Not.Null); Assert.That(result.Count, Is.EqualTo(expectedUsers.Count)); Assert.That(result.Select(u => u.Id), Is.EquivalentTo(expectedUsers.Select(u => u.Id))); } [Test] public async Task Given_InvalidDateOnly_When_FindByCreatedDate_Should_Throw_NotFoundByKeyException() { // Arrange var date = _fixture.Create(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act & Assert Assert.ThrowsAsync>(async () => await userRepository.FindUsersByCreatedDateAsync(date)); } [Test] public async Task Given_ValidUser_When_AddUser_Then_CreateUser() { var user = _fixture.Create(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act userRepository.AddAsync(user); var res = context.Users.Find(user.Id); // Assert Assert.That(res, Is.Not.Null); Assert.That(res.Username, Is.EqualTo(user.Username)); Assert.That(res.Id, Is.EqualTo(user.Id)); } [Test] public async Task Given_InvalidUser_When_AddUser_Should_Throw_AdditionUserException() { var user = _fixture.Create(); user.Username = string.Empty; await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act & Assert Assert.ThrowsAsync(async () => await userRepository.AddAsync(user)); } [Test] public async Task Given_ValidUser_When_ExistUser_Then_True() { // Arrange var user = _fixture.Create(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); context.Users.Add(user); await context.SaveChangesAsync(); // Act var res = await userRepository.ExistsAsync(user); // Assert Assert.That(res, Is.True); } [Test] public async Task Given_ValidUserButNotInDB_When_ExistUser_Then_False() { // Arrange var user = _fixture.Create(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act var res = await userRepository.ExistsAsync(user); // Assert Assert.That(res, Is.False); } [Test] public async Task Given_InvalidUser_When_ExistUser_Should_Throw_InvalidObjectException() { // Arrange await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act & Assert Assert.ThrowsAsync>(async () => await userRepository.ExistsAsync(default)); } [Test] public async Task Given_ValidUserId_When_ExistUserById_Then_True() { // Arrange var user = _fixture.Create(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); context.Users.Add(user); await context.SaveChangesAsync(); // Act var res = await userRepository.ExistsByIdAsync(user.Id); // Assert Assert.That(res, Is.True); } [Test] public async Task Given_ValidUserIdButNotInDB_When_ExistUser_Then_False() { // Arrange var user = _fixture.Create(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act var res = await userRepository.ExistsByIdAsync(user.Id); // Assert Assert.That(res, Is.False); } [Test] public async Task Given_ValidUsername_When_ExistUserById_Then_True() { // Arrange var user = _fixture.Create(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); context.Users.Add(user); await context.SaveChangesAsync(); // Act var res = await userRepository.ExistsUsernameAsync(user.Username); // Assert Assert.That(res, Is.True); } [Test] public async Task Given_ValidUsernameButNotInDB_When_ExistUser_Then_False() { // Arrange var user = _fixture.Create(); await using var context = new GovorDbContext(_options); var userRepository = new UsersRepository(context, _userValidator); // Act var res = await userRepository.ExistsUsernameAsync(user.Username); // Assert Assert.That(res, Is.False); } }