using System.Data.Common;
using EntitlementBLL.Common;
using EntitlementBLL.Implementations;
using EntitlementBLL.Interfaces;
using EntitlementBLL.Options;
using EntitlementDAL.DTOs;
using EntitlementDAL.Interfaces;
using GB5Shared.DTO.Framework.CommonConfig;
using GB5Shared.DTO.Framework.Login;
using GB5Shared.GenerateAutoNumber;
using GB5Shared.QueryExecutor;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Moq;
using Xunit;
namespace EntitlementTests;
///
/// ECDSA bundle sign/verify round-trip — all repos mocked, no real DB/Redis. Uses the
/// dev-fallback ephemeral key path (EcdsaKeyOptions left empty) since no real key is committed.
///
public class EntitlementBundleTests
{
private static (EntitlementBundleService svc, Mock bundleDal) BuildService()
{
var entitlementService = new Mock();
entitlementService
.Setup(s => s.GetResolvedBundleAsync(It.IsAny(), It.IsAny()))
.ReturnsAsync(new EntitlementBundleDto
{
TenantId = 42,
Subscriptions = new List { 1 },
Entitlements = new List
{
new() { Feature = "MOD.INVENTORY", Enabled = true }
},
Licenses = new Dictionary(),
BetaPrograms = new List(),
ValidUntil = DateTime.UtcNow.AddHours(1),
IssuedAt = DateTime.UtcNow
});
var bundleDal = new Mock();
bundleDal.Setup(b => b.ExpirePriorCurrentAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
.Returns(Task.CompletedTask);
bundleDal.Setup(b => b.SaveAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
.Returns(Task.CompletedTask);
// Real AutoNumber wired to a mocked IQueryExecutor — AutoNumber.GetNumberAsync is not
// virtual, so it can't be mocked directly; instead mock the QueryAsync call it makes
// internally to simulate the MAUTONUMBER increment round-trip.
var queryExecutor = new Mock();
queryExecutor
.Setup(q => q.QueryAsync(It.IsAny(), It.IsAny(), It.IsAny