using DocumentFormat.OpenXml.Wordprocessing; using Microsoft.Extensions.Logging; using Moq; using MoreLinq; using NUnit.Framework; using Strata.ContinuousImprovement.Biz.Configuration; using Strata.ContinuousImprovement.Biz.DbContexts; 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.SqlTools.Configuration.Common.AsyncFactory; using Strata.StrataSphereCompare.Client; using Strata.StrataSphereCompare.Client.Models; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using VerifyNUnit; using VerifyTests; 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 ExplorationServiceTest { private const string SourceFilePath = @"Exploration/source/"; public IAsyncDbContextFactory DbContextFactory { get; set; } public JazzEntityFrameworkFactory JAZZ_Framework { get; set; } public JazzDbContext JazzDbContext { get; set; } public ISqlGridReaderWrapper SqlGridReader { get; set; } public ISnowflakeDatabaseContext SnowflakeDatabaseContext { get; set; } public IConfigurationService ConfigurationService { get; set; } public IFiscalMonthResolver FiscalMonthResolver { get; set; } public ILogger Logger { get; set; } public VerifySettings VerifySettings { get; set; } public IFeatureFlagWrapper FeatureFlagWrapper { get; set; } public IStrataSphereCompareService StrataSphereCompareService { get; set; } public IExplorationFilterService ExplorationFilterService { get; set; } [OneTimeSetUp] public void ExplorationServiceTestOneTimeSetUp() { DbContextFactory = Mock.Of>(); JAZZ_Framework = new JazzEntityFrameworkFactory(); Mock.Get(DbContextFactory) .Setup(s => s.CreateDbContextAsync(It.IsAny())) .Returns(async () => { JazzDbContext = await JAZZ_Framework.CreateDbContextAsync(CancellationToken.None); return JazzDbContext; }); SqlGridReader = Mock.Of(); Mock.Get(SqlGridReader) .Setup(s => s.Read(It.IsAny())) .Returns(Enumerable.Empty()); SnowflakeDatabaseContext = Mock.Of(); Mock.Get(SnowflakeDatabaseContext) .Setup(s => s.QueryMultipleAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.FromResult(SqlGridReader)); ConfigurationService = Mock.Of(); FiscalMonthResolver = Mock.Of(); Logger = Mock.Of>(); VerifySettings = TestExtensions.TestSettings(); FeatureFlagWrapper = Mock.Of(); StrataSphereCompareService = Mock.Of(); ExplorationFilterService = Mock.Of(); // Setup the mock to return empty results Mock.Get(ExplorationFilterService) .Setup(s => s.GetFilterStringsAsync(It.IsAny>(), It.IsAny(), It.IsAny())) .ReturnsAsync(("", "")); Mock.Get(ExplorationFilterService) .Setup(s => s.BuildDataFiltersAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(new CostDetailsFilterDto()); Mock.Get(ExplorationFilterService) .Setup(s => s.CreateCostDriverFilter()) .Returns(new FilterChipItem()); Mock.Get(FeatureFlagWrapper) .Setup(f => f.IsCiBenchmarkingEnabled(It.IsAny())) .ReturnsAsync(true); } [TestCaseSource(nameof(GetCaseTypeFamilyDetailsTestCases))] public async Task GetCaseTypeFamilyDetailsTest(GetCaseTypeFamilyDetailsTestData data) { // arrange Mock.Get(SqlGridReader) .Setup(s => s.Read(It.IsAny())) .Returns(data.CTFGroupCalcsList); Mock.Get(SqlGridReader) .Setup(s => s.Read(It.IsAny())) .Returns(data.EntityGroupCalcsList); Mock.Get(SqlGridReader) .Setup(s => s.Read(It.IsAny())) .Returns(data.EntityCodeGroupCalcsList); Mock.Get(SqlGridReader) .Setup(s => s.Read(It.IsAny())) .Returns(data.EntityCodePhysicianGroupCalcsList); Mock.Get(SqlGridReader) .Setup(s => s.Read(It.IsAny())) .Returns(data.CTFEncounterDetailList); var explorationService = new ExplorationService( DbContextFactory, SnowflakeDatabaseContext, FiscalMonthResolver, FeatureFlagWrapper, StrataSphereCompareService, ExplorationFilterService, Logger); // act var taskResult = await explorationService.GetCaseTypeFamilyDetailsAsync(data.ExplorationDetailInfoData, CancellationToken.None); // assert await Verifier.Verify(taskResult, VerifySettings) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCaseSource(nameof(GetEncountersTestCases))] public async Task GetEncountersTest(GetEncountersTestData data) { // arrange Mock.Get(SqlGridReader) .Setup(s => s.Read(It.IsAny())) .Returns(data.PhysicianInfoList); Mock.Get(SqlGridReader) .Setup(s => s.Read(It.IsAny())) .Returns(data.EncounterInfoBaseList); var configurationGuid = Guid.Empty; var explorationService = new ExplorationService( DbContextFactory, SnowflakeDatabaseContext, FiscalMonthResolver, FeatureFlagWrapper, StrataSphereCompareService, ExplorationFilterService, Logger); // act var taskResult = await explorationService.GetEncountersAsync(data.ExplorationDetailInfoData, configurationGuid, CancellationToken.None); // assert await Verifier.Verify(taskResult, VerifySettings) .UseFileName(TestContext.CurrentContext.TestName()); } private static IEnumerable GetCaseTypeFamilyDetailsTestCases() { var testName = "GetCaseTypeFamilyDetailsTest"; var explorationDetailInfoDataJson = GetSourceFile("ExplorationDetailInfo.txt"); var ctfGroupCalcsListJson = GetSourceFile("CTFGroupCalcs.txt"); var entityGroupCalcsListJson = GetSourceFile("EntityGroupCalcs.txt"); var entityCodeGroupCalcsListJson = GetSourceFile("EntityCodeGroupCalcs.txt"); var entityCodePhysicianGroupCalcsListJson = GetSourceFile("EntityCodePhysicianGroupCalcs.txt"); var ctfEncounterDetailListJson = GetSourceFile("CTFEncounterDetail.txt"); var dataAllMatch = new GetCaseTypeFamilyDetailsTestData() { ExplorationDetailInfoData = JsonSerializer.Deserialize(explorationDetailInfoDataJson), CTFGroupCalcsList = JsonSerializer.Deserialize>(ctfGroupCalcsListJson), EntityGroupCalcsList = JsonSerializer.Deserialize>(entityGroupCalcsListJson), EntityCodeGroupCalcsList = JsonSerializer.Deserialize>(entityCodeGroupCalcsListJson), EntityCodePhysicianGroupCalcsList = JsonSerializer.Deserialize>(entityCodePhysicianGroupCalcsListJson), CTFEncounterDetailList = JsonSerializer.Deserialize>(ctfEncounterDetailListJson) }; dataAllMatch.ExplorationDetailInfoData.Filters = new ExplorationFilter() // FIXED: Changed from Biz.Exploration.Filters.Filter to ExplorationFilter { FilterChipItems = new List() { new FilterChipItem { ChipType = ChipType.DateRange, Key = ChipKey.DischargeDateID, DateRange = new List() { new DateTime(2024, 1, 1), new DateTime(2024, 12, 31) } } } }; yield return new TestCaseData(dataAllMatch) .SetName($"{testName} All Match"); var dataPhysicianIdNotMatch = new GetCaseTypeFamilyDetailsTestData() { ExplorationDetailInfoData = dataAllMatch.ExplorationDetailInfoData, CTFGroupCalcsList = dataAllMatch.CTFGroupCalcsList, EntityGroupCalcsList = dataAllMatch.EntityGroupCalcsList, EntityCodeGroupCalcsList = dataAllMatch.EntityCodeGroupCalcsList, EntityCodePhysicianGroupCalcsList = JsonSerializer.Deserialize>(entityCodePhysicianGroupCalcsListJson), CTFEncounterDetailList = dataAllMatch.CTFEncounterDetailList }; dataPhysicianIdNotMatch.EntityCodePhysicianGroupCalcsList.First().PhysicianId = 0; yield return new TestCaseData(dataPhysicianIdNotMatch) .SetName($"{testName} PhysicianId Not Match"); var dataCodeNotMatch = new GetCaseTypeFamilyDetailsTestData() { ExplorationDetailInfoData = dataAllMatch.ExplorationDetailInfoData, CTFGroupCalcsList = dataAllMatch.CTFGroupCalcsList, EntityGroupCalcsList = dataAllMatch.EntityGroupCalcsList, EntityCodeGroupCalcsList = JsonSerializer.Deserialize>(entityCodeGroupCalcsListJson), EntityCodePhysicianGroupCalcsList = dataAllMatch.EntityCodePhysicianGroupCalcsList, CTFEncounterDetailList = dataAllMatch.CTFEncounterDetailList }; dataCodeNotMatch.EntityCodeGroupCalcsList.First().Code = ""; yield return new TestCaseData(dataCodeNotMatch) .SetName($"{testName} Code Not Match"); var dataEntityNotMatch = new GetCaseTypeFamilyDetailsTestData() { ExplorationDetailInfoData = dataAllMatch.ExplorationDetailInfoData, CTFGroupCalcsList = dataAllMatch.CTFGroupCalcsList, EntityGroupCalcsList = JsonSerializer.Deserialize>(entityGroupCalcsListJson), EntityCodeGroupCalcsList = dataAllMatch.EntityCodeGroupCalcsList, EntityCodePhysicianGroupCalcsList = dataAllMatch.EntityCodePhysicianGroupCalcsList, CTFEncounterDetailList = dataAllMatch.CTFEncounterDetailList }; dataEntityNotMatch.EntityGroupCalcsList.First().EntityId = 0; yield return new TestCaseData(dataEntityNotMatch) .SetName($"{testName} Entity Not Match"); } private static IEnumerable GetEncountersTestCases() { var testName = "GetEncountersTest"; var explorationDetailInfoDataJson = GetSourceFile("ExplorationDetailInfo.txt"); var physicianInfoJson = GetSourceFile("PhysicianInfo.txt"); var encounterInfoBaseJson = GetSourceFile("EncounterInfoBase.txt"); var dataAllMatch = new GetEncountersTestData() { ExplorationDetailInfoData = JsonSerializer.Deserialize(explorationDetailInfoDataJson), PhysicianInfoList = JsonSerializer.Deserialize>(physicianInfoJson), EncounterInfoBaseList = JsonSerializer.Deserialize>(encounterInfoBaseJson) }; dataAllMatch.ExplorationDetailInfoData.Filters = new ExplorationFilter() // FIXED: Changed from Biz.Exploration.Filters.Filter to ExplorationFilter { FilterChipItems = new List() { new FilterChipItem { ChipType = ChipType.DateRange, Key = ChipKey.DischargeDateID, DateRange = new List() { new DateTime(2024, 1, 1), new DateTime(2024, 12, 31) } } } }; yield return new TestCaseData(dataAllMatch) .SetName($"{testName} All Match"); var dataPhysicianIdNotMatch = new GetEncountersTestData() { ExplorationDetailInfoData = dataAllMatch.ExplorationDetailInfoData, PhysicianInfoList = JsonSerializer.Deserialize>(physicianInfoJson), EncounterInfoBaseList = dataAllMatch.EncounterInfoBaseList, }; dataPhysicianIdNotMatch.PhysicianInfoList.First().PhysicianID = 0; yield return new TestCaseData(dataPhysicianIdNotMatch) .SetName($"{testName} PhysicianId Not Match"); } private static string GetSourceFile(string file) { string filePath = Path.Combine(TestHelper.TestsRootDirectory, SourceFilePath, file); string jsonData = File.ReadAllText(filePath); return jsonData; } public class GetCaseTypeFamilySummariesTestData { public ExplorationInfo ExplorationInfoData { get; set; } public IEnumerable CaseTypeFamilyEncounterInfoList { get; set; } } public class GetCaseTypeFamilyDetailsTestData { public ExplorationDetailInfo ExplorationDetailInfoData { get; set; } public IEnumerable CTFGroupCalcsList { get; set; } public IEnumerable EntityGroupCalcsList { get; set; } public IEnumerable EntityCodeGroupCalcsList { get; set; } public IEnumerable EntityCodePhysicianGroupCalcsList { get; set; } public IEnumerable CTFEncounterDetailList { get; set; } } public class GetEncountersTestData { public ExplorationDetailInfo ExplorationDetailInfoData { get; set; } public IEnumerable PhysicianInfoList { get; set; } public IEnumerable EncounterInfoBaseList { get; set; } } } }