Files

297 lines
13 KiB
C#

using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
using Strata.ContinuousImprovement.Biz.DbContexts.Snowflake;
using Strata.ContinuousImprovement.Biz.Exploration;
using Strata.ContinuousImprovement.Biz.Exploration.CaseTypeFamilies;
using Strata.ContinuousImprovement.Biz.Exploration.Filters;
using Strata.ContinuousImprovement.Biz.FiscalMonths;
using Strata.ContinuousImprovement.Biz.Test.Unit.Utilities;
using Strata.ContinuousImprovement.Biz.Utilities;
using Strata.ContinuousImprovement.JazzEntityFrameworkStub;
using Strata.CoreLib.Claims;
using Strata.StrataSphereCompare.Client;
using Strata.StrataSphereCompare.Client.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using static Strata.ContinuousImprovement.Biz.Exploration.ExplorationService;
using ExplorationFilter = Strata.ContinuousImprovement.Biz.Exploration.Filters.Filter;
namespace Strata.ContinuousImprovement.Biz.Test.Unit.Exploration
{
[TestFixture, Category("Unit")]
public class ExplorationServiceBenchmarkingUnitTests
{
private const string FeatureFlagKey = "cibenchmarkingenabled";
private const string CaseTypeFamilyName = "Sample CTF";
private Mock<ISnowflakeDatabaseContext> _snowflakeDatabaseContextMock;
private Mock<IFiscalMonthResolver> _fiscalMonthResolverMock;
private Mock<IClaimsPrincipalAccessor> _claimsPrincipalAccessorMock;
private Mock<IStrataSphereCompareService> _strataSphereCompareServiceMock;
private Mock<ILogger<ExplorationService>> _explorationServiceLoggerMock;
private Mock<IExplorationFilterService> _explorationFilterServiceMock;
private ExplorationInfo _explorationInfo;
[OneTimeSetUp]
public void OneTimeSetUp()
{
_snowflakeDatabaseContextMock = new Mock<ISnowflakeDatabaseContext>();
_fiscalMonthResolverMock = new Mock<IFiscalMonthResolver>();
_explorationServiceLoggerMock = new Mock<ILogger<ExplorationService>>();
var principal = TestUtilities.GetClaimsPrincipalAccessor();
var defaultUser = principal.GetCurrentClaimsPrincipal();
_claimsPrincipalAccessorMock = new Mock<IClaimsPrincipalAccessor>();
_claimsPrincipalAccessorMock.Setup(a => a.GetCurrentClaimsPrincipal()).Returns(defaultUser);
_strataSphereCompareServiceMock = new Mock<IStrataSphereCompareService>();
_explorationFilterServiceMock = new Mock<IExplorationFilterService>();
// Setup ExplorationFilterService mock
_explorationFilterServiceMock
.Setup(s => s.GetFilterStringsAsync(It.IsAny<IEnumerable<FilterChipItem>>(), It.IsAny<IQueryParamBase>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(("", ""));
_explorationFilterServiceMock
.Setup(s => s.BuildDataFiltersAsync(It.IsAny<CaseTypeFamily>(), It.IsAny<string>(), It.IsAny<ExplorationFilter>(), It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new CostDetailsFilterDto());
// Setup 1: For GetCaseTypeFamilySummariesAsync (no drill down filter)
_strataSphereCompareServiceMock
.Setup(s => s.GetCostDetailsAsync(
It.IsAny<BaseComparisonParams>(),
It.Is<CostDetailsFilterDto>(filter => filter.CostDetailsFilterDrillDown == null),
It.IsAny<CancellationToken>()))
.ReturnsAsync(new[]
{
new CostDetailsDto
{
AprDrgCaseTypeFamilyName = CaseTypeFamilyName,
P50th_VariableDirectCost = 250.75m,
P50th_Alos = 5.2m
}
});
// Setup 2: For GetCaseTypeFamilySummaryDetailsAsync (with drill down filter)
_strataSphereCompareServiceMock
.Setup(s => s.GetCostDetailsAsync(
It.IsAny<BaseComparisonParams>(),
It.Is<CostDetailsFilterDto>(filter => filter.CostDetailsFilterDrillDown != null),
It.IsAny<CancellationToken>()))
.ReturnsAsync(new[]
{
new CostDetailsDto
{
SphChargeCodeCostDriver = "LOS",
P50th_VariableDirectCost = 150.50m,
P50th_Alos = 3.2m
},
new CostDetailsDto
{
SphChargeCodeCostDriver = "Surgery",
P50th_VariableDirectCost = 300.25m,
P50th_Alos = 4.8m
}
});
// Summary Mock Data
_snowflakeDatabaseContextMock
.Setup(s => s.QueryAsync<CaseTypeFamilySummaryInfo>(
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object>(), It.IsAny<TimeSpan>()))
.ReturnsAsync(new[]
{
new CaseTypeFamilySummaryInfo { CaseTypeFamilyName = CaseTypeFamilyName }
});
// Summary Detail Mock Data - for GetCaseTypeFamilySummaryDetailsAsync
_snowflakeDatabaseContextMock
.Setup(s => s.QueryAsync<CaseTypeFamilyEncounterInfo>(
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object>(), It.IsAny<TimeSpan>()))
.ReturnsAsync(new[]
{
new CaseTypeFamilyEncounterInfo
{
CaseTypeFamilyName = CaseTypeFamilyName,
CostDriver = "LOS"
},
new CaseTypeFamilyEncounterInfo
{
CaseTypeFamilyName = CaseTypeFamilyName,
CostDriver = "Surgery"
}
});
_explorationInfo = new ExplorationCostDriverInfo
{
CaseTypeFamilyId = 1,
PeerGroupId = 1,
ExclusionCriteria = new ExclusionCriteria
{
LosExclusionType = ExclusionCriteriaType.None,
CostExclusionType = ExclusionCriteriaType.None
},
Filters = new ExplorationFilter // Use the alias
{
FilterChipItems = new List<FilterChipItem>
{
new FilterChipItem
{
ChipType = ChipType.DateRange,
Key = ChipKey.DischargeDateID,
DateRange = new List<DateTime>
{
new DateTime(2024, 1, 1),
new DateTime(2024, 12, 31)
}
}
}
}
};
}
[Test]
public async Task GetCaseTypeFamilySummariesAsync_FeatureFlagOn_PopulatesPeerMetrics()
{
// Arrange
var jazzFactory = new JazzEntityFrameworkFactory();
await jazzFactory.CreateDbContextAsync(CancellationToken.None);
var featureFlagWrapper = Mock.Of<IFeatureFlagWrapper>();
Mock.Get(featureFlagWrapper)
.Setup(f => f.IsCiBenchmarkingEnabled(It.IsAny<bool>()))
.ReturnsAsync(true);
var service = new ExplorationService(
jazzFactory,
_snowflakeDatabaseContextMock.Object,
_fiscalMonthResolverMock.Object,
featureFlagWrapper,
_strataSphereCompareServiceMock.Object,
_explorationFilterServiceMock.Object,
_explorationServiceLoggerMock.Object);
// Act
var summaries = await service.GetCaseTypeFamilySummariesAsync(_explorationInfo, CancellationToken.None);
var summary = summaries.Single(s => s.Name == CaseTypeFamilyName);
// Assert
Assert.That(summary.Data.PeerMedianCost, Is.EqualTo(250.75d));
Assert.That(summary.Data.PeerMedianALos, Is.EqualTo(5.2d));
}
[Test]
public async Task GetCaseTypeFamilySummariesAsync_FeatureFlagOff_DefaultPeerMetrics()
{
// Arrange
var jazzFactory = new JazzEntityFrameworkFactory();
await jazzFactory.CreateDbContextAsync(CancellationToken.None);
var featureFlagWrapper = Mock.Of<IFeatureFlagWrapper>();
Mock.Get(featureFlagWrapper)
.Setup(f => f.IsCiBenchmarkingEnabled(It.IsAny<bool>()))
.ReturnsAsync(false);
var service = new ExplorationService(
jazzFactory,
_snowflakeDatabaseContextMock.Object,
_fiscalMonthResolverMock.Object,
featureFlagWrapper,
_strataSphereCompareServiceMock.Object,
_explorationFilterServiceMock.Object,
_explorationServiceLoggerMock.Object);
// Act
var summaries = await service.GetCaseTypeFamilySummariesAsync(_explorationInfo, CancellationToken.None);
var summary = summaries.Single(s => s.Name == CaseTypeFamilyName);
// Assert
Assert.That(summary.Data.PeerMedianCost, Is.EqualTo(0d));
Assert.That(summary.Data.PeerMedianALos, Is.EqualTo(0d));
}
[Test, Ignore("Feature flag is not enabled, this might need additional refactoring")]
public async Task GetCaseTypeFamilySummaryDetailsAsync_FeatureFlagOn_PopulatesPeerMetrics()
{
// Arrange
var jazzFactory = new JazzEntityFrameworkFactory();
await jazzFactory.CreateDbContextAsync(CancellationToken.None);
var featureFlagWrapper = Mock.Of<IFeatureFlagWrapper>();
Mock.Get(featureFlagWrapper)
.Setup(f => f.IsCiBenchmarkingEnabled(It.IsAny<bool>()))
.ReturnsAsync(true);
var service = new ExplorationService(
jazzFactory,
_snowflakeDatabaseContextMock.Object,
_fiscalMonthResolverMock.Object,
featureFlagWrapper,
_strataSphereCompareServiceMock.Object,
_explorationFilterServiceMock.Object,
_explorationServiceLoggerMock.Object);
// Act
var summaries = await service.GetCaseTypeFamilySummaryDetailsAsync(_explorationInfo, CancellationToken.None);
var summary = summaries.Single();
// Assert
Assert.That(summary, Is.Not.Null);
Assert.That(summary.Name, Is.EqualTo(CaseTypeFamilyName));
Assert.That(summary.Children, Is.Not.Null.And.Not.Empty);
var losChild = summary.Children.FirstOrDefault(c => c.Name == "LOS");
if (losChild != null)
{
Assert.That(losChild.Data.PeerMedianCost, Is.EqualTo(150.50d));
}
var surgeryChild = summary.Children.FirstOrDefault(c => c.Name == "Surgery");
if (surgeryChild != null)
{
Assert.That(surgeryChild.Data.PeerMedianCost, Is.EqualTo(300.25d));
}
}
[Test]
public async Task GetCaseTypeFamilySummaryDetailsAsync_FeatureFlagOff_DefaultPeerMetrics()
{
// Arrange
var jazzFactory = new JazzEntityFrameworkFactory();
await jazzFactory.CreateDbContextAsync(CancellationToken.None);
var featureFlagWrapper = Mock.Of<IFeatureFlagWrapper>();
Mock.Get(featureFlagWrapper)
.Setup(f => f.IsCiBenchmarkingEnabled(It.IsAny<bool>()))
.ReturnsAsync(false);
var service = new ExplorationService(
jazzFactory,
_snowflakeDatabaseContextMock.Object,
_fiscalMonthResolverMock.Object,
featureFlagWrapper,
_strataSphereCompareServiceMock.Object,
_explorationFilterServiceMock.Object,
_explorationServiceLoggerMock.Object);
// Act
var summaries = await service.GetCaseTypeFamilySummaryDetailsAsync(_explorationInfo as ExplorationCostDriverInfo, CancellationToken.None);
var summary = summaries.Single();
// Assert
Assert.That(summary, Is.Not.Null);
Assert.That(summary.Name, Is.EqualTo(CaseTypeFamilyName));
if (summary.Children != null && summary.Children.Any())
{
foreach (var child in summary.Children)
{
Assert.That(child.Data.PeerMedianCost, Is.EqualTo(0d));
Assert.That(child.Data.PeerMedianALos, Is.EqualTo(0d));
}
}
}
}
}