Files
ERP_Distribution/Distribution.Tests/Services/RegionServiceTests.cs
T
DeepnaPooja 4e12e9f8f1 Update RegionServiceTests for the new RegionService constructor
RegionService now depends on ICurrentUserService and IScopeAccessService
for the target/budget/tax-rule/agency scope checks; update the existing
CRUD test setup to mock them accordingly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 22:45:43 +05:30

199 lines
5.9 KiB
C#

using Distribution.Features.Region;
using Distribution.Infra.Authorization;
using Distribution.Infra.UoW;
using Distribution.Models;
using Moq;
using Xunit;
namespace Distribution.Tests.Services;
public class RegionServiceTests
{
private readonly Mock<IRegionRepository> _repo = new();
private readonly Mock<IUnitOfWork> _uow = new();
private readonly Mock<ICurrentUserService> _currentUser = new();
private readonly Mock<IScopeAccessService> _scopeAccess = new();
private readonly RegionService _sut;
public RegionServiceTests()
{
_currentUser.Setup(u => u.RoleLevel).Returns(60);
_sut = new RegionService(_repo.Object, _uow.Object, _currentUser.Object, _scopeAccess.Object);
}
private static Region ActiveRegion(string name = "North") =>
new() { Id = Guid.NewGuid(), Name = name, IsActive = true };
private static Region InactiveRegion() =>
new() { Id = Guid.NewGuid(), Name = "Old", IsActive = false };
// GetAllAsync
[Fact]
public async Task GetAllAsync_ReturnsOnlyActiveRegions()
{
_repo.Setup(r => r.GetAllAsync()).ReturnsAsync([ActiveRegion(), InactiveRegion()]);
var result = await _sut.GetAllAsync();
Assert.Single(result);
Assert.True(result[0].IsActive);
}
[Fact]
public async Task GetAllAsync_ReturnsEmpty_WhenNoneActive()
{
_repo.Setup(r => r.GetAllAsync()).ReturnsAsync([InactiveRegion()]);
var result = await _sut.GetAllAsync();
Assert.Empty(result);
}
// GetByIdAsync
[Fact]
public async Task GetByIdAsync_ReturnsNull_WhenNotFound()
{
_repo.Setup(r => r.GetByIdAsync(It.IsAny<Guid>())).ReturnsAsync((Region?)null);
var result = await _sut.GetByIdAsync(Guid.NewGuid());
Assert.Null(result);
}
[Fact]
public async Task GetByIdAsync_ReturnsNull_WhenInactive()
{
_repo.Setup(r => r.GetByIdAsync(It.IsAny<Guid>())).ReturnsAsync(InactiveRegion());
var result = await _sut.GetByIdAsync(Guid.NewGuid());
Assert.Null(result);
}
[Fact]
public async Task GetByIdAsync_ReturnsResponse_WhenActiveRegionFound()
{
var region = ActiveRegion("South");
_repo.Setup(r => r.GetByIdAsync(region.Id)).ReturnsAsync(region);
var result = await _sut.GetByIdAsync(region.Id);
Assert.NotNull(result);
Assert.Equal("South", result.Name);
Assert.Equal(region.Id, result.Id);
}
// CreateAsync
[Fact]
public async Task CreateAsync_AddsRegion_AndCommits()
{
var request = new CreateRegionRequest("East");
var result = await _sut.CreateAsync(request);
_uow.Verify(u => u.BeginAsync(default), Times.Once);
_repo.Verify(r => r.AddAsync(It.Is<Region>(x => x.Name == "East")), Times.Once);
_uow.Verify(u => u.CommitAsync(default), Times.Once);
Assert.Equal("East", result.Name);
}
[Fact]
public async Task CreateAsync_Rollbacks_WhenAddThrows()
{
_repo.Setup(r => r.AddAsync(It.IsAny<Region>())).ThrowsAsync(new Exception("db error"));
await Assert.ThrowsAsync<Exception>(() => _sut.CreateAsync(new CreateRegionRequest("X")));
_uow.Verify(u => u.RollbackAsync(default), Times.Once);
_uow.Verify(u => u.CommitAsync(default), Times.Never);
}
// UpdateAsync
[Fact]
public async Task UpdateAsync_ReturnsNull_WhenNotFound()
{
_repo.Setup(r => r.GetByIdAsync(It.IsAny<Guid>())).ReturnsAsync((Region?)null);
var result = await _sut.UpdateAsync(Guid.NewGuid(), new UpdateRegionRequest("New"));
Assert.Null(result);
_uow.Verify(u => u.BeginAsync(default), Times.Never);
}
[Fact]
public async Task UpdateAsync_ReturnsNull_WhenInactive()
{
_repo.Setup(r => r.GetByIdAsync(It.IsAny<Guid>())).ReturnsAsync(InactiveRegion());
var result = await _sut.UpdateAsync(Guid.NewGuid(), new UpdateRegionRequest("New"));
Assert.Null(result);
}
[Fact]
public async Task UpdateAsync_UpdatesName_AndCommits()
{
var region = ActiveRegion("Old Name");
_repo.Setup(r => r.GetByIdAsync(region.Id)).ReturnsAsync(region);
var result = await _sut.UpdateAsync(region.Id, new UpdateRegionRequest("New Name"));
Assert.NotNull(result);
Assert.Equal("New Name", result.Name);
_uow.Verify(u => u.BeginAsync(default), Times.Once);
_uow.Verify(u => u.CommitAsync(default), Times.Once);
}
// DeleteAsync
[Fact]
public async Task DeleteAsync_ReturnsFalse_WhenNotFound()
{
_repo.Setup(r => r.GetByIdAsync(It.IsAny<Guid>())).ReturnsAsync((Region?)null);
var result = await _sut.DeleteAsync(Guid.NewGuid());
Assert.False(result);
_uow.Verify(u => u.BeginAsync(default), Times.Never);
}
[Fact]
public async Task DeleteAsync_ReturnsFalse_WhenInactive()
{
_repo.Setup(r => r.GetByIdAsync(It.IsAny<Guid>())).ReturnsAsync(InactiveRegion());
var result = await _sut.DeleteAsync(Guid.NewGuid());
Assert.False(result);
}
[Fact]
public async Task DeleteAsync_CallsRemove_AndCommits()
{
var region = ActiveRegion();
_repo.Setup(r => r.GetByIdAsync(region.Id)).ReturnsAsync(region);
var result = await _sut.DeleteAsync(region.Id);
Assert.True(result);
_repo.Verify(r => r.Remove(region), Times.Once);
_uow.Verify(u => u.CommitAsync(default), Times.Once);
}
[Fact]
public async Task DeleteAsync_Rollbacks_WhenRemoveThrows()
{
var region = ActiveRegion();
_repo.Setup(r => r.GetByIdAsync(region.Id)).ReturnsAsync(region);
_repo.Setup(r => r.Remove(It.IsAny<Region>())).Throws(new Exception("db error"));
await Assert.ThrowsAsync<Exception>(() => _sut.DeleteAsync(region.Id));
_uow.Verify(u => u.RollbackAsync(default), Times.Once);
}
}