diff --git a/Homeworks/UnitTests/src/PromoCodeFactory.UnitTests/PromoCodeFactory.UnitTests.csproj b/Homeworks/UnitTests/src/PromoCodeFactory.UnitTests/PromoCodeFactory.UnitTests.csproj index d616f72f..184d87e9 100644 --- a/Homeworks/UnitTests/src/PromoCodeFactory.UnitTests/PromoCodeFactory.UnitTests.csproj +++ b/Homeworks/UnitTests/src/PromoCodeFactory.UnitTests/PromoCodeFactory.UnitTests.csproj @@ -9,6 +9,7 @@ + diff --git a/Homeworks/UnitTests/src/PromoCodeFactory.UnitTests/WebHost/Controllers/Partners/SetPartnerPromoCodeLimitAsyncTests.cs b/Homeworks/UnitTests/src/PromoCodeFactory.UnitTests/WebHost/Controllers/Partners/SetPartnerPromoCodeLimitAsyncTests.cs index cb748461..97a07cf3 100644 --- a/Homeworks/UnitTests/src/PromoCodeFactory.UnitTests/WebHost/Controllers/Partners/SetPartnerPromoCodeLimitAsyncTests.cs +++ b/Homeworks/UnitTests/src/PromoCodeFactory.UnitTests/WebHost/Controllers/Partners/SetPartnerPromoCodeLimitAsyncTests.cs @@ -1,7 +1,271 @@ -namespace PromoCodeFactory.UnitTests.WebHost.Controllers.Partners +using AutoFixture; +using AutoFixture.AutoMoq; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Moq; +using PromoCodeFactory.Core.Abstractions.Repositories; +using PromoCodeFactory.Core.Domain.PromoCodeManagement; +using PromoCodeFactory.DataAccess; +using PromoCodeFactory.DataAccess.Repositories; +using PromoCodeFactory.WebHost.Controllers; +using PromoCodeFactory.WebHost.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Xunit; + +namespace PromoCodeFactory.UnitTests.WebHost.Controllers.Partners { public class SetPartnerPromoCodeLimitAsyncTests { //TODO: Add Unit Tests + private readonly Mock> _partnersRepositoryMock; + private readonly PartnersController _partnersController; + private readonly IFixture _fixture; + + public SetPartnerPromoCodeLimitAsyncTests() + { + _fixture = new Fixture().Customize(new AutoMoqCustomization()); + _partnersRepositoryMock = _fixture.Freeze>>(); + _partnersController = _fixture.Build().OmitAutoProperties().Create(); + } + + /// + /// 1. Если партнер не найден, то также нужно выдать ошибку 404; + /// + /// + [Fact] + public async Task SetPartnerPromoCodeLimitAsync_PartnerIsNotFound_ReturnsNotFound() + { + // Arrange + _partnersRepositoryMock.Setup(repo => repo.GetByIdAsync(It.IsAny())) + .ReturnsAsync(() => null); + + // Act + var result = await _partnersController.SetPartnerPromoCodeLimitAsync(Guid.NewGuid(), new()); + + // Assert + result.Should().BeAssignableTo(); + } + + /// + /// 2. Если партнер заблокирован, то есть поле IsActive = false в классе Partner, то также нужно выдать ошибку 400; + /// + /// + [Fact] + public async Task SetPartnerPromoCodeLimitAsync_PartnerIsNoActive_ReturnsBadRequest() + { + // Arrange + _partnersRepositoryMock.Setup(repo => repo.GetByIdAsync(It.IsAny())) + .ReturnsAsync(new Partner { IsActive = false }); + + // Act + var result = await _partnersController.SetPartnerPromoCodeLimitAsync(Guid.NewGuid(), new()); + + // Assert + result.Should().BeAssignableTo(); + } + + /// + /// 3.1 Если партнеру выставляется лимит, то мы должны обнулить количество промокодов, которые партнер выдал NumberIssuedPromoCodes + /// + /// + [Fact] + public async Task SetPartnerPromoCodeLimitAsync_PartnerNumberIssuedPromoCodesEqualZero_ReturnsTrue() + { + // Arrange + IEnumerable partnerPromoCodeLimit = _fixture + .Build() + .With(p => p.CancelDate, () => null) + .OmitAutoProperties() + .CreateMany(2); + + Partner partner = _fixture.Build() + .With(p => p.NumberIssuedPromoCodes, 100) + .With(p => p.PartnerLimits, partnerPromoCodeLimit.ToList()) + .Create(); + + SetPartnerPromoCodeLimitRequest setPartnerPromoCodeLimitRequest = _fixture.Build() + .With(p => p.Limit, 1) + .Create(); + + _partnersRepositoryMock.Setup(repo => repo.GetByIdAsync(partner.Id)) + .ReturnsAsync(partner); + + // Act + var result = await _partnersController.SetPartnerPromoCodeLimitAsync(partner.Id, setPartnerPromoCodeLimitRequest); + + // Assert + partner.NumberIssuedPromoCodes.Should().Be(0); + } + + /// + /// 3.2 Если партнеру выставляется лимит, если лимит закончился, то количество не обнуляется; + /// + /// + [Fact] + public async Task SetPartnerPromoCodeLimitAsync_PartnerPromoCodeLimitCancelDateNotNull_ReturnsTrue() + { + // Arrange + IEnumerable partnerPromoCodeLimit = _fixture.Build() + .With(p => p.CancelDate, DateTime.UtcNow) + .OmitAutoProperties() + .CreateMany(2); + + Partner partner = _fixture.Build() + .With(p => p.NumberIssuedPromoCodes, 100) + .With(p => p.PartnerLimits, partnerPromoCodeLimit.ToList()) + .Create(); + + SetPartnerPromoCodeLimitRequest setPartnerPromoCodeLimitRequest = _fixture.Build() + .With(p => p.Limit, 1) + .Create(); + + _partnersRepositoryMock.Setup(repo => repo.GetByIdAsync(partner.Id)) + .ReturnsAsync(partner); + + // Act + var result = await _partnersController.SetPartnerPromoCodeLimitAsync(partner.Id, setPartnerPromoCodeLimitRequest); + + // Assert + partner.NumberIssuedPromoCodes.Should().NotBe(0); + } + + /// + /// 4. При установке лимита нужно отключить предыдущий лимит; + /// + /// + [Fact] + public async Task SetPartnerPromoCodeLimitAsync_PartnerPreviousLimitDisabled_ReturnsTrue() + { + // Arrange + IEnumerable partnerPromoCodeLimit = _fixture.Build() + .With(p => p.CancelDate, () => null) + .OmitAutoProperties() + .CreateMany(1); + Partner partner = _fixture.Build() + .With(p => p.PartnerLimits, partnerPromoCodeLimit.ToList()) + .Create(); + + SetPartnerPromoCodeLimitRequest setPartnerPromoCodeLimitRequest = _fixture.Build() + .With(p => p.Limit, 1) + .Create(); + + _partnersRepositoryMock.Setup(repo => repo.GetByIdAsync(partner.Id)) + .ReturnsAsync(partner); + + // Act + var result = await _partnersController.SetPartnerPromoCodeLimitAsync(partner.Id, setPartnerPromoCodeLimitRequest); + + // Assert + partner.PartnerLimits.Count.Should().BeGreaterThan(1); + partner.PartnerLimits.ToList()[0].CancelDate.Should().NotBeNull(); + } + + /// + /// 5.1 Лимит должен быть больше 0; + /// + /// + /// + [Theory] + [InlineData(1)] + [InlineData(2)] + public async Task SetPartnerPromoCodeLimitAsync_PartnerLimitMoreThanZero_ReturnsTrue(int limit) + { + // Arrange + IEnumerable partnerPromoCodeLimit = _fixture.Build() + .OmitAutoProperties() + .CreateMany(2); + + Partner partner = _fixture.Build() + .With(p => p.PartnerLimits, partnerPromoCodeLimit.ToList()) + .Create(); + + SetPartnerPromoCodeLimitRequest setPartnerPromoCodeLimitRequest = _fixture.Build() + .With(p => p.Limit, limit) + .Create(); + + _partnersRepositoryMock.Setup(repo => repo.GetByIdAsync(partner.Id)) + .ReturnsAsync(partner); + + // Act + var result = await _partnersController.SetPartnerPromoCodeLimitAsync(partner.Id, setPartnerPromoCodeLimitRequest); + + //Assert + partner.PartnerLimits.ToList()[partner.PartnerLimits.Count - 1].Limit.Should().BePositive(); + } + + /// + /// 5.2 Лимит должен быть больше 0; + /// + /// + /// + [Theory] + [InlineData(0)] + [InlineData(-1)] + public async Task SetPartnerPromoCodeLimitAsync_PartnerLimitLessOrEqualZero_ReturnsBadRequest(int limit) + { + // Arrange + IEnumerable partnerPromoCodeLimit = _fixture.Build() + .OmitAutoProperties() + .CreateMany(2); + + Partner partner = _fixture.Build() + .With(p => p.PartnerLimits, partnerPromoCodeLimit.ToList()) + .Create(); + + SetPartnerPromoCodeLimitRequest setPartnerPromoCodeLimitRequest = _fixture.Build() + .With(p => p.Limit, limit) + .Create(); + + _partnersRepositoryMock.Setup(repo => repo.GetByIdAsync(partner.Id)) + .ReturnsAsync(partner); + + // Act + var result = await _partnersController.SetPartnerPromoCodeLimitAsync(partner.Id, setPartnerPromoCodeLimitRequest); + + //Assert + result.Should().BeAssignableTo(); + } + + // 6. Нужно убедиться, что сохранили новый лимит в базу данных(это нужно проверить Unit-тестом); + [Fact] + public async Task SetPartnerPromoCodeLimitAsync_PartnerLimitIsSaveInDataBase_ReturnsTrue() + { + // Arrange + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .Options; + var dataContext = new DataContext(options); + + var partnersRepository = new EfRepository(dataContext); + _fixture.Inject>(partnersRepository); + var partnersController = _fixture.Build() + .OmitAutoProperties() + .Create(); + + IEnumerable partnerPromoCodeLimit = _fixture.Build() + .OmitAutoProperties() + .CreateMany(1); + Partner partner = _fixture.Build() + .With(p => p.PartnerLimits, partnerPromoCodeLimit.ToList()) + .Create(); + + await partnersRepository.AddAsync(partner); + + SetPartnerPromoCodeLimitRequest setPartnerPromoCodeLimitRequest = _fixture.Build() + .With(p => p.Limit, 1) + .Create(); + + // Act + var result = await partnersController.SetPartnerPromoCodeLimitAsync(partner.Id, setPartnerPromoCodeLimitRequest); + + // Assert + result.Should().BeOfType(); + Partner partnerSaved = await partnersRepository.GetByIdAsync(partner.Id); + partnerSaved.PartnerLimits.ToList()[1].Limit.Should().Be(1); + } } } \ No newline at end of file