using System.Data.Common;
using EntitlementBLL.Exceptions;
using EntitlementBLL.Implementations;
using EntitlementDAL.DTOs;
using EntitlementDAL.Interfaces;
using GB5Shared.DTO.Framework.Login;
using GB5Shared.QueryExecutor;
using Moq;
using Xunit;
namespace EntitlementTests;
///
/// Covers the new ILicenseBLL.GetSeatsByClientAsync — the ownership-safe, client-facing equivalent
/// of GetSeatsAsync(subscriptionId,...), which has no ownership check at all. A client can only
/// ever supply their own ClientId (from JWT claims, never a SubscriptionId), so this resolves the
/// caller's own subscription first via ISubscriptionDAL before ever touching license rows.
///
public class LicenseBLLTests
{
private static LoginDTO TestLogin() => new() { ClientId = 42, UserId = -1 };
[Fact]
public async Task Test_GetSeatsByClientAsync_ClientHasSubscription_ReturnsItsSeats()
{
var subscriptionDal = new Mock();
var licenseDal = new Mock();
var queryExecutor = new Mock();
subscriptionDal.Setup(d => d.GetByClientAsync(42, It.IsAny(), It.IsAny()))
.ReturnsAsync(new SubscriptionDTO { SubscriptionId = 10, ClientId = 42 });
licenseDal.Setup(d => d.GetBySubscriptionAsync(10, It.IsAny(), It.IsAny()))
.ReturnsAsync(new List { new() { LicenseId = 1, SubscriptionId = 10, LicenseType = 0, Seats = 5 } });
var svc = new LicenseBLL(licenseDal.Object, subscriptionDal.Object, queryExecutor.Object);
var result = await svc.GetSeatsByClientAsync(42, TestLogin(), CancellationToken.None);
Assert.Single(result);
licenseDal.Verify(d => d.GetBySubscriptionAsync(10, It.IsAny(), It.IsAny()), Times.Once);
}
[Fact]
public async Task Test_GetSeatsByClientAsync_ClientHasNoSubscription_Throws_NeverQueriesLicenses()
{
var subscriptionDal = new Mock();
var licenseDal = new Mock();
var queryExecutor = new Mock();
subscriptionDal.Setup(d => d.GetByClientAsync(99, It.IsAny(), It.IsAny()))
.ReturnsAsync((SubscriptionDTO?)null);
var svc = new LicenseBLL(licenseDal.Object, subscriptionDal.Object, queryExecutor.Object);
await Assert.ThrowsAsync(
() => svc.GetSeatsByClientAsync(99, TestLogin(), CancellationToken.None));
licenseDal.Verify(d => d.GetBySubscriptionAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never);
}
}