using MicCheck.Api.Data; using MicCheck.Api.Features.Usage; using MicCheck.Api.Tests.Unit.TestSupport; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using Moq; using NUnit.Framework; namespace MicCheck.Api.Tests.Unit.Features.Usage; [TestFixture] public class FeatureUsageControllerTests { private Mock _db = null!; private List _usage = null!; private IMemoryCache _cache = null!; private FeatureUsageController _controller = null!; private const int EnvironmentId = 1; [SetUp] public void SetUp() { _db = new Mock(); _usage = []; _db.SetupDbSet(c => c.FeatureUsageDaily, _usage); _cache = new MemoryCache(new MemoryCacheOptions()); _controller = new FeatureUsageController(new FeatureUsageQueryService(_db.Object), _cache); } [Test] public async Task WhenGettingDashboardUsageWithNoData_ThenEmptyResultsAreReturned() { var result = await _controller.GetDashboardUsage(EnvironmentId); var ok = result.Result as OkObjectResult; var response = (DashboardUsageResponse)ok!.Value!; Assert.That(response.TopFeaturesLastDay, Is.Empty); } [Test] public async Task WhenGettingDashboardUsageASecondTime_ThenTheCachedResultIsReturnedWithoutQueryingAgain() { var first = await _controller.GetDashboardUsage(EnvironmentId); _usage.Add(new FeatureUsageDaily { EnvironmentId = EnvironmentId, FeatureId = 1, FeatureName = "flag", UsageDate = DateOnly.FromDateTime(DateTime.UtcNow), Count = 100, UpdatedAt = DateTimeOffset.UtcNow }); var second = await _controller.GetDashboardUsage(EnvironmentId); var firstOk = (DashboardUsageResponse)((OkObjectResult)first.Result!).Value!; var secondOk = (DashboardUsageResponse)((OkObjectResult)second.Result!).Value!; Assert.That(secondOk, Is.SameAs(firstOk)); } [Test] public async Task WhenGettingDashboardUsageForDifferentDayRanges_ThenEachRangeIsCachedSeparately() { var sevenDays = await _controller.GetDashboardUsage(EnvironmentId, days: 7); var fourteenDays = await _controller.GetDashboardUsage(EnvironmentId, days: 14); var sevenOk = (DashboardUsageResponse)((OkObjectResult)sevenDays.Result!).Value!; var fourteenOk = (DashboardUsageResponse)((OkObjectResult)fourteenDays.Result!).Value!; Assert.That(sevenOk, Is.Not.SameAs(fourteenOk)); } [Test] public async Task WhenDaysExceedsTheMaximum_ThenItIsClampedTo90() { _usage.Add(new FeatureUsageDaily { EnvironmentId = EnvironmentId, FeatureId = 1, FeatureName = "flag", UsageDate = DateOnly.FromDateTime(DateTime.UtcNow), Count = 5, UpdatedAt = DateTimeOffset.UtcNow }); var clamped = await _controller.GetDashboardUsage(EnvironmentId, days: 1000); var explicitNinety = await _controller.GetDashboardUsage(EnvironmentId, days: 90); var clampedOk = (DashboardUsageResponse)((OkObjectResult)clamped.Result!).Value!; var explicitOk = (DashboardUsageResponse)((OkObjectResult)explicitNinety.Result!).Value!; Assert.That(clampedOk.DailyUsage.Count, Is.EqualTo(explicitOk.DailyUsage.Count)); } }