Files
ERP_Distribution/Distribution.Tests/Services/OrderServiceTests.cs
Kalana B. Thilakarathna 4673d72d53 test project created
2026-08-19 14:40:04 +05:30

230 lines
7.4 KiB
C#

using Distribution.Features.Order;
using Distribution.Infra.Authorization;
using Distribution.Infra.UoW;
using Distribution.Models;
using Moq;
using Xunit;
namespace Distribution.Tests.Services;
public class OrderServiceTests
{
private readonly Mock<IOrderRepository> _repo = new();
private readonly Mock<IUnitOfWork> _uow = new();
private readonly Mock<ICurrentUserService> _currentUser = new();
private readonly Mock<IScopeAccessService> _scopeAccess = new();
private readonly OrderService _sut;
public OrderServiceTests()
{
_sut = new OrderService(_repo.Object, _uow.Object, _currentUser.Object, _scopeAccess.Object);
}
private static Order ActiveOrder(Guid storeId) => new()
{
Id = Guid.NewGuid(),
FK_StoreId = storeId,
OrderDate = DateTime.Now,
TotalAmount = 100,
IsActive = true
};
private void SetupGlobalUser(Guid userId)
{
_currentUser.Setup(u => u.UserId).Returns(userId);
_currentUser.Setup(u => u.RoleLevel).Returns(50);
}
private void SetupScopedUser(Guid userId)
{
_currentUser.Setup(u => u.UserId).Returns(userId);
_currentUser.Setup(u => u.RoleLevel).Returns(10);
}
// GetAllAsync
[Fact]
public async Task GetAllAsync_GlobalUser_ReturnsAllActiveOrders()
{
var userId = Guid.NewGuid();
var storeA = Guid.NewGuid();
var storeB = Guid.NewGuid();
SetupGlobalUser(userId);
var orders = new List<Order> { ActiveOrder(storeA), ActiveOrder(storeB) };
_repo.Setup(r => r.GetAllAsync()).ReturnsAsync(orders);
_repo.Setup(r => r.GetItemsByOrderIdAsync(It.IsAny<Guid>())).ReturnsAsync([]);
var result = await _sut.GetAllAsync();
Assert.Equal(2, result.Count);
}
[Fact]
public async Task GetAllAsync_ScopedUser_FiltersToAccessibleStores()
{
var userId = Guid.NewGuid();
var accessibleStore = Guid.NewGuid();
var restrictedStore = Guid.NewGuid();
SetupScopedUser(userId);
_scopeAccess.Setup(s => s.GetAccessibleStoreIdsAsync(userId)).ReturnsAsync([accessibleStore]);
var orders = new List<Order> { ActiveOrder(accessibleStore), ActiveOrder(restrictedStore) };
_repo.Setup(r => r.GetAllAsync()).ReturnsAsync(orders);
_repo.Setup(r => r.GetItemsByOrderIdAsync(It.IsAny<Guid>())).ReturnsAsync([]);
var result = await _sut.GetAllAsync();
Assert.Single(result);
Assert.Equal(accessibleStore, result[0].StoreId);
}
[Fact]
public async Task GetAllAsync_FiltersOutInactiveOrders()
{
var userId = Guid.NewGuid();
SetupGlobalUser(userId);
var inactiveOrder = ActiveOrder(Guid.NewGuid());
inactiveOrder.IsActive = false;
_repo.Setup(r => r.GetAllAsync()).ReturnsAsync([inactiveOrder]);
_repo.Setup(r => r.GetItemsByOrderIdAsync(It.IsAny<Guid>())).ReturnsAsync([]);
var result = await _sut.GetAllAsync();
Assert.Empty(result);
}
// GetByIdAsync
[Fact]
public async Task GetByIdAsync_ReturnsNull_WhenOrderNotFound()
{
SetupGlobalUser(Guid.NewGuid());
_repo.Setup(r => r.GetByIdAsync(It.IsAny<Guid>())).ReturnsAsync((Order?)null);
var result = await _sut.GetByIdAsync(Guid.NewGuid());
Assert.Null(result);
}
[Fact]
public async Task GetByIdAsync_ReturnsNull_WhenUserLacksStoreScope()
{
var userId = Guid.NewGuid();
var storeId = Guid.NewGuid();
SetupScopedUser(userId);
_repo.Setup(r => r.GetByIdAsync(It.IsAny<Guid>())).ReturnsAsync(ActiveOrder(storeId));
_scopeAccess.Setup(s => s.HasStoreScopeAsync(userId, storeId)).ReturnsAsync(false);
var result = await _sut.GetByIdAsync(Guid.NewGuid());
Assert.Null(result);
}
[Fact]
public async Task GetByIdAsync_ReturnsOrder_WhenGlobalUser()
{
var userId = Guid.NewGuid();
var order = ActiveOrder(Guid.NewGuid());
SetupGlobalUser(userId);
_repo.Setup(r => r.GetByIdAsync(order.Id)).ReturnsAsync(order);
_repo.Setup(r => r.GetItemsByOrderIdAsync(order.Id)).ReturnsAsync([]);
var result = await _sut.GetByIdAsync(order.Id);
Assert.NotNull(result);
Assert.Equal(order.Id, result.Id);
}
// CreateAsync
[Fact]
public async Task CreateAsync_ReturnsNull_WhenUserLacksStoreScope()
{
var userId = Guid.NewGuid();
var storeId = Guid.NewGuid();
SetupScopedUser(userId);
_scopeAccess.Setup(s => s.HasStoreScopeAsync(userId, storeId)).ReturnsAsync(false);
var result = await _sut.CreateAsync(
new CreateOrderRequest(storeId, DateTime.Now, 100, []));
Assert.Null(result);
_uow.Verify(u => u.BeginAsync(default), Times.Never);
}
[Fact]
public async Task CreateAsync_CreatesOrder_WhenGlobalUser()
{
var userId = Guid.NewGuid();
var storeId = Guid.NewGuid();
SetupGlobalUser(userId);
_repo.Setup(r => r.AddAsync(It.IsAny<Order>())).Returns(Task.CompletedTask);
_repo.Setup(r => r.AddItemsAsync(It.IsAny<IEnumerable<OrderItem>>())).Returns(Task.CompletedTask);
var result = await _sut.CreateAsync(
new CreateOrderRequest(storeId, DateTime.Now, 250, []));
Assert.NotNull(result);
Assert.Equal(storeId, result.StoreId);
Assert.Equal(250, result.TotalAmount);
_uow.Verify(u => u.BeginAsync(default), Times.Once);
_uow.Verify(u => u.CommitAsync(default), Times.Once);
}
[Fact]
public async Task CreateAsync_Rollbacks_OnException()
{
var userId = Guid.NewGuid();
SetupGlobalUser(userId);
_repo.Setup(r => r.AddAsync(It.IsAny<Order>())).ThrowsAsync(new Exception("db error"));
await Assert.ThrowsAsync<Exception>(() =>
_sut.CreateAsync(new CreateOrderRequest(Guid.NewGuid(), DateTime.Now, 100, [])));
_uow.Verify(u => u.RollbackAsync(default), Times.Once);
_uow.Verify(u => u.CommitAsync(default), Times.Never);
}
// DeleteAsync
[Fact]
public async Task DeleteAsync_ReturnsFalse_WhenOrderNotFound()
{
SetupGlobalUser(Guid.NewGuid());
_repo.Setup(r => r.GetByIdAsync(It.IsAny<Guid>())).ReturnsAsync((Order?)null);
var result = await _sut.DeleteAsync(Guid.NewGuid());
Assert.False(result);
}
[Fact]
public async Task DeleteAsync_ReturnsFalse_WhenUserLacksStoreScope()
{
var userId = Guid.NewGuid();
var storeId = Guid.NewGuid();
SetupScopedUser(userId);
_repo.Setup(r => r.GetByIdAsync(It.IsAny<Guid>())).ReturnsAsync(ActiveOrder(storeId));
_scopeAccess.Setup(s => s.HasStoreScopeAsync(userId, storeId)).ReturnsAsync(false);
var result = await _sut.DeleteAsync(Guid.NewGuid());
Assert.False(result);
_uow.Verify(u => u.BeginAsync(default), Times.Never);
}
[Fact]
public async Task DeleteAsync_RemovesOrder_WhenAuthorized()
{
var userId = Guid.NewGuid();
var order = ActiveOrder(Guid.NewGuid());
SetupGlobalUser(userId);
_repo.Setup(r => r.GetByIdAsync(order.Id)).ReturnsAsync(order);
var result = await _sut.DeleteAsync(order.Id);
Assert.True(result);
_repo.Verify(r => r.Remove(order), Times.Once);
_uow.Verify(u => u.CommitAsync(default), Times.Once);
}
}