using Contracts.DTO; using Contracts.Repositories; using Contracts.SearchModels; using Contracts.ViewModels; using Moq; using Services.Domain; using Services.Support.Exceptions; using Services.Tests.Support.Fakes.Database; using Services.Tests.Support.Fakes.Repositories; namespace Services.Tests.Domain; public class ChangeRecordServiceTests { [Theory] [InlineData(50)] [InlineData(-50)] public async Task Create_WhenUserExists_ThenChangeBalance_ReturnsChangeRecordViewModel(int recordSum, int userBalance = 100) { var userRepoFake = new UserRepoFake(); var changeRecordRepoMock = new Mock(); changeRecordRepoMock.Setup(repo => repo.Create(It.IsAny())).ReturnsAsync(new ChangeRecordDto()); var changeRecordService = new ChangeRecordService(changeRecordRepoMock.Object, userRepoFake); // Add user var user = new UserDto() { Id = Guid.NewGuid(), Balance = userBalance }; await userRepoFake.Create(user); var changeRecord = new ChangeRecordDto { UserId = user.Id, Sum = recordSum, SpendingGroupId = Guid.NewGuid() }; var result = await changeRecordService.Create(changeRecord); changeRecordRepoMock.Verify(repo => repo.Create(It.IsAny()), Times.Once); Assert.NotNull(result); Assert.IsType(result); var existedUser = await userRepoFake.Get(new UserSearch { Id = user.Id }); Assert.Equal(existedUser.Balance, userBalance + recordSum); DbFake.ClearDb(); } [Theory] [InlineData(50)] [InlineData(-50)] public async Task Delete_WhenUserExists_ThenChangeBalance_ReturnsChangeRecordViewModel(int recordSum, int userBalance = 100) { var user = new UserDto() { Id = Guid.NewGuid(), Balance = userBalance }; var changeRecord = new ChangeRecordDto { UserId = user.Id, Sum = recordSum, SpendingGroupId = Guid.NewGuid() }; var userRepoFake = new UserRepoFake(); var changeRecordRepoMock = new Mock(); changeRecordRepoMock.Setup(repo => repo.Delete(It.IsAny())).ReturnsAsync(changeRecord); changeRecordRepoMock.Setup(repo => repo.Create(It.IsAny())).ReturnsAsync(new ChangeRecordDto()); var changeRecordService = new ChangeRecordService(changeRecordRepoMock.Object, userRepoFake); // Add user and record await userRepoFake.Create(user); await changeRecordService.Create(changeRecord); var result = await changeRecordService.Delete(new ChangeRecordSearch { Id = changeRecord.Id }); changeRecordRepoMock.Verify(repo => repo.Delete(It.IsAny()), Times.Once); Assert.NotNull(result); Assert.IsType(result); var existedUser = await userRepoFake.Get(new UserSearch { Id = user.Id }); Assert.Equal(existedUser.Balance, userBalance); DbFake.ClearDb(); } [Fact] public void Delete_WhenRecordNotFound_ThenThrowsEntityNotFoundException() { var changeRecordRepoMock = new Mock(); var userRepoMock = new Mock(); changeRecordRepoMock.Setup(repo => repo.Delete(It.IsAny())).ReturnsAsync((ChangeRecordDto)null); var changeRecordService = new ChangeRecordService(changeRecordRepoMock.Object, userRepoMock.Object); Assert.ThrowsAsync(() => changeRecordService.Delete(new())); } [Fact] public async Task GetList_ReturnsChangeRecordViewModels() { var changeRecordRepoMock = new Mock(); var userRepoMock = new Mock(); changeRecordRepoMock.Setup(repo => repo.GetList(It.IsAny())).ReturnsAsync(GetAllChangeRecords()); var changeRecordService = new ChangeRecordService(changeRecordRepoMock.Object, userRepoMock.Object); var result = await changeRecordService.GetList(); changeRecordRepoMock.Verify(repo => repo.GetList(It.IsAny()), Times.Once); Assert.NotNull(result); Assert.IsType>(result.ToList()); } [Theory] [InlineData(50, 25)] [InlineData(-50, 25)] public async Task Update_WhenUserExists_ThenChangeBalance_ReturnsChangeRecordViewModel(int recordSum, int recorNewSum, int userBalance = 100) { var user = new UserDto() { Id = Guid.NewGuid(), Balance = userBalance }; var changeRecord = new ChangeRecordDto { UserId = user.Id, Sum = recordSum, SpendingGroupId = Guid.NewGuid() }; var userRepoFake = new UserRepoFake(); var changeRecordRepoMock = new Mock(); changeRecordRepoMock.Setup(repo => repo.Update(It.IsAny())).ReturnsAsync(changeRecord); changeRecordRepoMock.Setup(repo => repo.Create(It.IsAny())).ReturnsAsync(new ChangeRecordDto()); var changeRecordService = new ChangeRecordService(changeRecordRepoMock.Object, userRepoFake); // Add user and record await userRepoFake.Create(user); await changeRecordService.Create(changeRecord); var newChangeRecord = new ChangeRecordDto { Id = Guid.NewGuid(), UserId = user.Id, Sum = recorNewSum, SpendingGroupId = Guid.NewGuid() }; var result = await changeRecordService.Update(newChangeRecord); changeRecordRepoMock.Verify(repo => repo.Update(It.IsAny()), Times.Once); Assert.NotNull(result); Assert.IsType(result); var existedUser = await userRepoFake.Get(new UserSearch { Id = user.Id }); Assert.Equal(existedUser.Balance, userBalance + recorNewSum); DbFake.ClearDb(); } [Fact] public void Update_WhenRecordNotExists_ThenThrowsEntityNotFoundException() { var changeRecordRepoMock = new Mock(); changeRecordRepoMock.Setup(repo => repo.Update(It.IsAny())).ReturnsAsync((ChangeRecordDto?)null); var userRepoMock = new Mock(); var changeRecordService = new ChangeRecordService(changeRecordRepoMock.Object, userRepoMock.Object); var changeRecord = new ChangeRecordDto { Id = Guid.NewGuid(), UserId = Guid.NewGuid(), Sum = 50, SpendingGroupId = Guid.NewGuid() }; Assert.ThrowsAsync(() => changeRecordService.Update(changeRecord)); } public IEnumerable GetAllChangeRecords() => new List() { new ChangeRecordDto() { Id = Guid.NewGuid(), Sum = 50, SpendingGroupId = Guid.NewGuid(), UserId = Guid.NewGuid() }, new ChangeRecordDto() { Id = Guid.NewGuid(), Sum = 50, SpendingGroupId = Guid.NewGuid(), UserId = Guid.NewGuid() }, }; }