chore: deploy initial code base

This commit is contained in:
Thom Lamb
2026-05-12 10:34:30 -05:00
parent cce2961782
commit a81300a571
1829 changed files with 248331 additions and 1 deletions
@@ -0,0 +1,295 @@
using FluentAssertions;
using Moq;
using NUnit.Framework;
using Strata.ContinuousImprovement.Biz.Filter;
using Strata.ContinuousImprovement.Biz.Pagination;
using Strata.ContinuousImprovement.Biz.QualityVariation.Breakdowns;
using Strata.ContinuousImprovement.Biz.QualityVariation.Breakdowns.Filters;
using Strata.ContinuousImprovement.JazzEntityFrameworkStub;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Strata.ContinuousImprovement.Biz.Test.Unit.QualityVariation.Breakdowns
{
[TestFixture, Category("Unit")]
public class QVIBreakdownServiceTest
{
private Mock<IQVIBreakdownService> _qviBreakdownServiceMock;
[SetUp]
public void TestSetUp()
{
_qviBreakdownServiceMock = new Mock<IQVIBreakdownService>();
}
[TestCaseSource(nameof(GetFrameworkWithFilterData))]
public async Task TestGetPagedAsyncWithFramework(JazzEntityFrameworkFactory jazzEntityFrameworkFactory, QVIBreakdownFilters filters, CancellationToken cancellationToken)
{
// arrange
var qviBreakdownService = new QVIBreakdownService(jazzEntityFrameworkFactory, null, null);
try
{
// act
var taskResult = await qviBreakdownService
.GetPagedAsync(new PagingOptions(), filters, cancellationToken);
// assert
var result = taskResult.Data;
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
result.Should().BeNullOrEmpty();
return;
}
result.Should()
.NotBeNullOrEmpty()
.And.AllBeOfType<QVIBreakdown>();
if (filters.BreakdownIds.Any())
result.Should()
.Contain(vo => filters.BreakdownIds.Contains(vo.BreakdownId.ToString()));
}
catch (AssertionException)
{
// Intentionally left empty
}
catch (Exception e)
{
e.Should().BeOfType<OperationCanceledException>();
}
}
[Test]
public async Task TestFirstPage_Sorted_Asc()
{
// arrange
var qviBreakdownService = new QVIBreakdownService(new JazzEntityFrameworkFactory(), null, null);
var filters = new QVIBreakdownFilters()
{
IdentifiedSavings = 0,
BreakdownIds = new List<string>(),
ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345")
};
var pagingOptions = new PagingOptions() { SortField = "QVICasesTotal", SortOrder = SortOrder.Asc };
// act
var taskResult = await qviBreakdownService
.GetPagedAsync(pagingOptions, filters, CancellationToken.None);
// assert
taskResult.Data.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIBreakdown>()
.And.HaveCountGreaterThan(1);
taskResult.Data.First().QVICasesTotal
.Should().BeLessThan(taskResult.Data.Last().QVICasesTotal);
}
[Test]
public async Task TestFirstPage_Sorted_Desc()
{
// arrange
var qviBreakdownService = new QVIBreakdownService(new JazzEntityFrameworkFactory(), null, null);
var filters = new QVIBreakdownFilters()
{
IdentifiedSavings = 0,
BreakdownIds = new List<string>(),
ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345")
};
var pagingOptions = new PagingOptions() { SortField = "QVICasesTotal", SortOrder = SortOrder.Desc };
// act
var taskResult = await qviBreakdownService
.GetPagedAsync(pagingOptions, filters, CancellationToken.None);
// assert
taskResult.Data.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIBreakdown>()
.And.HaveCountGreaterThan(1);
taskResult.Data.First().QVICasesTotal
.Should().BeGreaterThan(taskResult.Data.Last().QVICasesTotal);
}
[TestCaseSource(nameof(GetFilterData))]
public void TestValidateFilters(QVIBreakdownFilters filters)
{
if (filters == null) return;
if (filters.BreakdownIds.Any())
filters.BreakdownIds.Should()
.AllBeOfType<string>()
.And.NotBeNullOrEmpty();
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworksWithCancellation))]
public async Task TestGetFilterOptionsAsync(JazzEntityFrameworkFactory jazzEntityFrameworkFactory, CancellationToken cancellationToken)
{
// arrange
var qviBreakdownService = new QVIBreakdownService(jazzEntityFrameworkFactory, null, null);
try
{
// act
var taskResult = await qviBreakdownService
.GetFilterOptionsAsync(new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345"), cancellationToken);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNull();
return;
}
taskResult.Should()
.BeOfType<QVIBreakdownFilterOptions>()
.And.NotBeNull();
taskResult.Breakdowns.Should().AllBeOfType<FilterMember>().And.NotBeNullOrEmpty()
.And.NotContain(cd => string.IsNullOrEmpty(cd.Id))
.And.NotContain(cd => string.IsNullOrEmpty(cd.Text));
}
catch (NotImplementedException nie)
{
nie.Should().BeOfType<NotImplementedException>();
}
catch (Exception e)
{
e.Should().BeOfType<OperationCanceledException>();
}
}
#region JazzDbService Tests
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworks))]
public async Task TestGetAllAsync(JazzEntityFrameworkFactory jazzEntityFrameworkFactory)
{
// arrange
var qviBreakdownService = new QVIBreakdownService(jazzEntityFrameworkFactory, null, null);
// act
var taskResult = await qviBreakdownService.GetAllAsync(CancellationToken.None);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNullOrEmpty();
}
else
{
taskResult.Should().NotBeNullOrEmpty();
}
}
[Test, Ignore("Broken due to removal of Key from VariationCaseType")]
public async Task TestGetAllAsync_Filtered()
{
// arrange
var factory = new JazzEntityFrameworkFactory();
var filters = factory.QVIOpportunities;
var qviBreakdownService = new QVIBreakdownService(factory, null, null);
// act
var taskResult = await qviBreakdownService.GetAllAsync(CancellationToken.None);
// assert
taskResult.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIBreakdown>()
.And.HaveCountGreaterThan(0)
.And.NotContain(o => string.IsNullOrEmpty(o.ToString()))
.And.Contain(o => filters.Select(f => f.BreakdownName).Contains(o.BreakdownName))
.And.Contain(o => filters.Select(f => f.ConfigurationGuid).Contains(o.ConfigurationGuid));
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworks)), Ignore("Complex key issue")]
public async Task TestGetById(JazzEntityFrameworkFactory jazzEntityFrameworkFactory)
{
// arrange
var qviBreakdownService = new QVIBreakdownService(jazzEntityFrameworkFactory, null, null);
var tempResult = await qviBreakdownService.GetAllAsync(CancellationToken.None);
// act
var taskResult =
await qviBreakdownService.GetById(tempResult.FirstOrDefault()?.BreakdownId ?? 1, CancellationToken.None);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNull();
}
else
{
taskResult.Should().NotBeNull()
.And.BeOfType<QVIBreakdown>();
}
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworks)), Ignore("Complex key issue")]
public async Task TestGetByIds(JazzEntityFrameworkFactory jazzEntityFrameworkFactory)
{
// arrange
var qviBreakdownService = new QVIBreakdownService(jazzEntityFrameworkFactory, null, null);
var tempResult = await qviBreakdownService.GetAllAsync(CancellationToken.None);
var ids = tempResult.Select(o => o.BreakdownId);
// act
var taskResult = await qviBreakdownService.GetByIds(ids, CancellationToken.None);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNullOrEmpty();
}
else
{
taskResult.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIBreakdown>();
}
}
#endregion
[TearDown]
public void TestTearDown()
{
// Method intentionally left empty.
}
#region TestCaseData
public static IEnumerable<TestCaseData> GetFilterData()
{
yield return new TestCaseData(new QVIBreakdownFilters { ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") }).SetName("No Filters");
yield return new TestCaseData(new QVIBreakdownFilters { IdentifiedSavings = 1999, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") }).SetName(
"By Identified Savings");
yield return new TestCaseData(new QVIBreakdownFilters { BreakdownIds = new[] { "1" }, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") })
.SetName("By Breakdown");
}
public static IEnumerable<TestCaseData> GetFrameworkWithFilterData()
{
var testCases = GetFilterData().ToList();
var jeffs = JazzEntityFrameworkFactory.GetFrameworksWithCancellation()
.Select(tcd => tcd.Arguments);
foreach (var tcd in jeffs)
{
var jeff = (JazzEntityFrameworkFactory)tcd[0];
var ct = (CancellationToken)tcd[1];
foreach (var testCase in testCases)
{
yield return new TestCaseData(jeff, testCase.Arguments.GetValue(0), ct)
.SetName($"{testCase.TestName} {(string.IsNullOrEmpty(jeff.TestName) ? "w/o Jeff" : "w/Jeff")}")
.SetCategory(jeff.TestName);
}
}
}
#endregion
}
}
@@ -0,0 +1,291 @@
using FluentAssertions;
using Moq;
using NUnit.Framework;
using Strata.ContinuousImprovement.Biz.Filter;
using Strata.ContinuousImprovement.Biz.Pagination;
using Strata.ContinuousImprovement.Biz.QualityVariation.Events;
using Strata.ContinuousImprovement.Biz.QualityVariation.Events.Filters;
using Strata.ContinuousImprovement.JazzEntityFrameworkStub;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Strata.ContinuousImprovement.Biz.Test.Unit.QualityVariation.Events
{
[TestFixture, Category("Unit")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Standard abbreviation")]
public class QVIEventServiceTest
{
private Mock<IQVIEventService> _qviEventSeriveMock;
[SetUp]
public void TestSetUp()
{
_qviEventSeriveMock = new Mock<IQVIEventService>();
}
[TestCaseSource(nameof(GetFrameworkWithFilterData))]
public async Task TestGetPagedAsyncWithFramework(JazzEntityFrameworkFactory jazzEntityFrameworkFactory, QVIEventFilters filters, CancellationToken cancellationToken)
{
// arrange
var qviEventService = new QVIEventService(jazzEntityFrameworkFactory, null, null);
try
{
// act
var taskResult = await qviEventService.GetPagedAsync(new PagingOptions(), filters, cancellationToken);
// assert
var result = taskResult.Data;
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
result.Should().BeNullOrEmpty();
return;
}
result.Should().NotBeNullOrEmpty().And.AllBeOfType<QVIEvent>();
if (filters.QualityVariationEventIds.Any())
result.Should()
.Contain(vo => filters.QualityVariationEventIds.Contains(vo.QualityVariationEventName.ToString()));
}
catch (AssertionException)
{
// Intentionally left empty
}
catch (Exception e)
{
e.Should().BeOfType<OperationCanceledException>();
}
}
[Test]
public async Task TestFirstPage_Sorted_Asc()
{
// arrange
var qviEventService = new QVIEventService(new JazzEntityFrameworkFactory(), null, null);
var filters = new QVIEventFilters()
{
QualityVariationEventIds = new List<string>(),
IdentifiedSavings = 0,
QVICases = 0,
ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345")
};
var pagingOptions = new PagingOptions() { SortField = "QVICasesTotal", SortOrder = SortOrder.Asc };
// act
var taskResult = await qviEventService.GetPagedAsync(pagingOptions, filters, CancellationToken.None);
// assert
taskResult.Data.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIEvent>()
.And.HaveCountGreaterThan(1);
taskResult.Data.First().QVICasesTotal.Should().BeLessThan(taskResult.Data.Last().QVICasesTotal);
}
[Test]
public async Task TestFirstPage_Sorted_Desc()
{
// arrange
var qviEventService = new QVIEventService(new JazzEntityFrameworkFactory(), null, null);
var filters = new QVIEventFilters()
{
QualityVariationEventIds = new List<string>(),
IdentifiedSavings = 0,
QVICases = 0,
ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345")
};
var pagingOptions = new PagingOptions() { SortField = "QVICasesTotal", SortOrder = SortOrder.Desc };
// act
var taskResult = await qviEventService
.GetPagedAsync(pagingOptions, filters, CancellationToken.None);
// assert
taskResult.Data.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIEvent>()
.And.HaveCountGreaterThan(1);
taskResult.Data.First().QVICasesTotal.Should().BeGreaterThan(taskResult.Data.Last().QVICasesTotal);
}
[TestCaseSource(nameof(GetFilterData))]
public void TestValidateFilters(QVIEventFilters filters)
{
if (filters == null) return;
if (filters.QualityVariationEventIds.Any())
filters.QualityVariationEventIds.Should()
.AllBeOfType<string>()
.And.NotBeNullOrEmpty();
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworksWithCancellation))]
public async Task TestGetFilterOptionsAsync(JazzEntityFrameworkFactory jazzEntityFrameworkFactory, CancellationToken cancellationToken)
{
// arrange
var qviEventService = new QVIEventService(jazzEntityFrameworkFactory, null, null);
try
{
// act
var taskResult = await qviEventService
.GetFilterOptionsAsync(new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345"), cancellationToken);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNull();
return;
}
taskResult.Should().BeOfType<QVIEventFilterOptions>().And.NotBeNull();
taskResult.QualityVariationEvents.Should().AllBeOfType<FilterMember>()
.And.NotBeNullOrEmpty()
.And.NotContain(cd => string.IsNullOrEmpty(cd.Id))
.And.NotContain(cd => string.IsNullOrEmpty(cd.Text));
}
catch (NotImplementedException nie)
{
nie.Should().BeOfType<NotImplementedException>();
}
catch (Exception e)
{
e.Should().BeOfType<OperationCanceledException>();
}
}
#region JazzDbService Tests
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworks))]
public async Task TestGetAllAsync(JazzEntityFrameworkFactory jazzEntityFrameworkFactory)
{
// arrange
var qviEventService = new QVIEventService(jazzEntityFrameworkFactory, null, null);
// act
var taskResult = await qviEventService.GetAllAsync(CancellationToken.None);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNullOrEmpty();
}
else
{
taskResult.Should().NotBeNullOrEmpty();
}
}
[Test, Ignore("Broken due to removal of Key from VariationCaseType")]
public async Task TestGetAllAsync_Filtered()
{
// arrange
var factory = new JazzEntityFrameworkFactory();
var filters = factory.QVIOpportunities;
var qviEventService = new QVIEventService(factory, null, null);
// act
var taskResult = await qviEventService.GetAllAsync(CancellationToken.None);
// assert
taskResult.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIEvent>()
.And.HaveCountGreaterThan(0)
.And.NotContain(o => string.IsNullOrEmpty(o.ToString()))
.And.Contain(o => filters.Select(f => f.QualityVariationEventName).Contains(o.QualityVariationEventName))
.And.Contain(o => filters.Select(f => f.ConfigurationGuid).Contains(o.ConfigurationGuid));
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworks)), Ignore("Complex key issue")]
public async Task TestGetById(JazzEntityFrameworkFactory jazzEntityFrameworkFactory)
{
// arrange
var qviEventService = new QVIEventService(jazzEntityFrameworkFactory, null, null);
var tempResult = await qviEventService.GetAllAsync(CancellationToken.None);
// act
var taskResult =
await qviEventService.GetById(tempResult.FirstOrDefault()?.QualityVariationEventId ?? 1, CancellationToken.None);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNull();
}
else
{
taskResult.Should().NotBeNull()
.And.BeOfType<QVIEvent>();
}
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworks)), Ignore("Complex key issue")]
public async Task TestGetByIds(JazzEntityFrameworkFactory jazzEntityFrameworkFactory)
{
// arrange
var qviEventService = new QVIEventService(jazzEntityFrameworkFactory, null, null);
var tempResult = await qviEventService.GetAllAsync(CancellationToken.None);
var ids = tempResult.Select(o => o.QualityVariationEventId);
// act
var taskResult = await qviEventService.GetByIds(ids, CancellationToken.None);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNullOrEmpty();
}
else
{
taskResult.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIEvent>();
}
}
#endregion
[TearDown]
public void TestTearDown()
{
// Method intentionally left empty.
}
#region TestCaseData
public static IEnumerable<TestCaseData> GetFilterData()
{
yield return new TestCaseData(new QVIEventFilters { ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") }).SetName("No Filters");
yield return new TestCaseData(new QVIEventFilters { IdentifiedSavings = 1999, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") }).SetName(
"By Identified Savings");
yield return new TestCaseData(new QVIEventFilters { QualityVariationEventIds = new[] { "1" }, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") })
.SetName("By Event ID");
}
public static IEnumerable<TestCaseData> GetFrameworkWithFilterData()
{
var testCases = GetFilterData().ToList();
var jeffs = JazzEntityFrameworkFactory.GetFrameworksWithCancellation()
.Select(tcd => tcd.Arguments);
foreach (var tcd in jeffs)
{
var jeff = (JazzEntityFrameworkFactory)tcd[0];
var ct = (CancellationToken)tcd[1];
foreach (var testCase in testCases)
{
yield return new TestCaseData(jeff, testCase.Arguments.GetValue(0), ct)
.SetName($"{testCase.TestName} {(string.IsNullOrEmpty(jeff.TestName) ? "w/o Jeff" : "w/Jeff")}")
.SetCategory(jeff.TestName);
}
}
}
#endregion
}
}
@@ -0,0 +1,642 @@
using ClosedXML.Excel;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
using Strata.ContinuousImprovement.Biz.Configuration;
using Strata.ContinuousImprovement.Biz.DbContexts;
using Strata.ContinuousImprovement.Biz.Filter;
using Strata.ContinuousImprovement.Biz.Generics;
using Strata.ContinuousImprovement.Biz.Initiatives;
using Strata.ContinuousImprovement.Biz.Pagination;
using Strata.ContinuousImprovement.Biz.QualityVariation.Opportunities;
using Strata.ContinuousImprovement.Biz.QualityVariation.Opportunities.Filters;
using Strata.ContinuousImprovement.Biz.Test.Unit.Utilities;
using Strata.ContinuousImprovement.JazzEntityFrameworkStub;
using Strata.SqlTools.Configuration.Common.AsyncFactory;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Strata.ContinuousImprovement.Biz.Test.Unit.QualityVariation.Opportunities
{
[TestFixture, Category("Unit")]
public class QVIOpportunityServiceTest
{
private Mock<IQVIOpportunityService> _qualityVariationItemOpportunityServiceMock;
private Mock<IAsyncDbContextFactory<JazzDbContext>> _dbContextFactoryMock;
private Mock<IJazzDbContext> _jazzDbContextMock;
private IInitiativeService _initiativeService;
private IUpdateFactOpportunitySavingsService _updateFactOpportunitySavingsService;
private IConfigurationService _configurationService;
private ILogger<QVIOpportunityService> _logger;
private static readonly ResourceFileExtractor _extractor = new ResourceFileExtractor(".Resource.");
[SetUp]
public void TestSetUp()
{
_qualityVariationItemOpportunityServiceMock = new Mock<IQVIOpportunityService>();
_dbContextFactoryMock = new Mock<IAsyncDbContextFactory<JazzDbContext>>();
_jazzDbContextMock = new Mock<IJazzDbContext>();
_initiativeService = Mock.Of<IInitiativeService>();
_updateFactOpportunitySavingsService = Mock.Of<IUpdateFactOpportunitySavingsService>();
_configurationService = Mock.Of<IConfigurationService>();
_logger = Mock.Of<ILogger<QVIOpportunityService>>();
Mock.Get(_initiativeService)
.Setup(s => s.DeleteAsync(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(true));
Mock.Get(_updateFactOpportunitySavingsService)
.Setup(s => s.UpdateFactOpportunitySavings(It.IsAny<CancellationToken>()));
Mock.Get(_configurationService)
.Setup(s => s.GetConfigurationAsync(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.ReturnsAsync((Guid guid, CancellationToken ct) => new Biz.Configuration.Configuration { ConfigurationGuid = guid });
}
[TestCaseSource(nameof(GetFrameworkWithFilterData))]
public async Task TestGetPagedAsyncWithFramework(JazzEntityFrameworkFactory jazzEntityFrameworkFactory, QVIFilters filters, CancellationToken cancellationToken)
{
// arrange
var qualityVariationItemOpportunityService = new QVIOpportunityService(jazzEntityFrameworkFactory, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
try
{
// act
var taskResult = await qualityVariationItemOpportunityService
.GetPagedAsync(new PagingOptions(), filters, cancellationToken);
// assert
var result = taskResult.Data;
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
result.Should().BeNullOrEmpty();
return;
}
result.Should()
.NotBeNullOrEmpty()
.And.AllBeOfType<QVIOpportunity>();
if (filters.BreakdownIds.Any())
result.Should()
.Contain(vo => filters.BreakdownIds.Contains(vo.BreakdownId.ToString()));
if (filters.ExcludeInitiatives)
{
result.ToList().ForEach(opportunity => opportunity.HasInitiative.Should().Be(false));
}
if (!string.IsNullOrEmpty(filters.OpportunitySearch))
result.Should()
.Contain(vo => vo.OpportunityKey.Contains(filters.OpportunitySearch));
}
catch (AssertionException)
{
// Intentionally left empty
}
catch (Exception e)
{
e.Should().BeOfType<OperationCanceledException>();
}
}
[Test]
public async Task TestFirstPage_Sorted_Asc()
{
// arrange
var qualityVariationItemOpportunityService = new QVIOpportunityService(new JazzEntityFrameworkFactory(), null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
var filters = new QVIFilters()
{
QualityVariationEventIds = new List<string>(),
IdentifiedSavings = 0,
BreakdownIds = new List<string>(),
ViewVisible = true,
ExcludeInitiatives = false,
OpportunitySearch = "",
ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345")
};
var pagingOptions = new PagingOptions() { SortField = "QVICases", SortOrder = SortOrder.Asc };
// act
var taskResult = await qualityVariationItemOpportunityService
.GetPagedAsync(new PagingOptions(), filters, CancellationToken.None);
// assert
taskResult.Data.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIOpportunity>()
.And.HaveCountGreaterThan(1);
taskResult.Data.First().QVICases
.Should().BeLessThan(taskResult.Data.Last().QVICases);
}
[Test]
public async Task TestFirstPage_Sorted_Desc()
{
// arrange
var qualityVariationItemOpportunityService = new QVIOpportunityService(new JazzEntityFrameworkFactory(), null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
var filters = new QVIFilters()
{
QualityVariationEventIds = new List<string>(),
IdentifiedSavings = 0,
BreakdownIds = new List<string>(),
ViewVisible = true,
ExcludeInitiatives = false,
OpportunitySearch = "",
ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345")
};
var pagingOptions = new PagingOptions() { SortField = "QVICases", SortOrder = SortOrder.Desc };
// act
var taskResult = await qualityVariationItemOpportunityService
.GetPagedAsync(pagingOptions, filters, CancellationToken.None);
// assert
taskResult.Data.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIOpportunity>()
.And.HaveCountGreaterThan(1);
taskResult.Data.First().QVICases
.Should().BeGreaterThan(taskResult.Data.Last().QVICases);
}
[TestCaseSource(nameof(GetFilterData))]
public void TestValidateFilters(QVIFilters filters)
{
if (filters == null) return;
if (filters.QualityVariationEventIds.Any())
filters.QualityVariationEventIds.Should()
.AllBeOfType<string>()
.And.NotBeNullOrEmpty();
if (filters.BreakdownIds.Any())
filters.BreakdownIds.Should()
.AllBeOfType<string>()
.And.NotBeNullOrEmpty();
}
[Test]
public async Task TestGetExcelWorkbook()
{
// arrange
var framework = new JazzEntityFrameworkFactory();
await framework.CreateDbContextAsync(CancellationToken.None);
var filters = new QVIFilters()
{
ConfigurationGuid = framework.Configurations.First().ConfigurationGuid,
BreakdownIds = new[] { framework.QVIOpportunities.First().BreakdownId.ToString() },
QualityVariationEventIds = new[]
{framework.QVIOpportunities.First().QualityVariationEventId.ToString()},
};
var service = new QVIOpportunityService(framework, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
// act
var wb = await service.ExportAsync(new SortOptions(), filters, CancellationToken.None);
#pragma warning disable S125 // Sections of code should not be commented out
//wb.SaveAs(System.IO.Path.Combine(@"C:\Git\continuousimprovement\tests\Strata.ContinuousImprovement.Biz.Test.Unit\Resource", "ExcelFilter.xlsx"));
#pragma warning restore S125 // Sections of code should not be commented out
// assert
wb.Worksheets.Should().HaveCount(1);
var ws = wb.Worksheet(1);
ws.Should().NotBeNull();
var expected = @"Examples.QualityVariationItemOpportunity.ExcelFilter.xlsx";
using (var expectedStream = _extractor.ReadFileFromResourceToStream(expected))
using (var actualStream = new MemoryStream())
{
wb.SaveAs(actualStream);
actualStream.Compare(expectedStream, out var message).Should().BeTrue(message);
}
}
[Test]
public async Task TestGetExcelWorkbookNullFilter()
{
// arrange
var framework = new JazzEntityFrameworkFactory();
await framework.CreateDbContextAsync(CancellationToken.None);
var service = new QVIOpportunityService(framework, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
// act
var wb = await service.ExportAsync(null, null, CancellationToken.None);
#pragma warning disable S125 // Sections of code should not be commented out
//wb.SaveAs(System.IO.Path.Combine(@"C:\Git\continuousimprovement\tests\Strata.ContinuousImprovement.Biz.Test.Unit\Resource", "ExcelNullFilter.xlsx"));
#pragma warning restore S125 // Sections of code should not be commented out
// assert
wb.Worksheets.Should().HaveCount(1);
var ws = wb.Worksheet(1);
ws.Should().NotBeNull();
var expected = @"Examples.QualityVariationItemOpportunity.ExcelNullFilter.xlsx";
using (var expectedStream = _extractor.ReadFileFromResourceToStream(expected))
using (var actualStream = new MemoryStream())
{
wb.SaveAs(actualStream);
actualStream.Compare(expectedStream, out var message).Should().BeTrue(message);
}
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworksWithCancellation))]
public async Task TestGetExcelWorkbookWithFramework(JazzEntityFrameworkFactory jazzEntityFrameworkFactory, CancellationToken cancellationToken)
{
// arrange
var variationOpportunityService = new QVIOpportunityService(jazzEntityFrameworkFactory, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
var filters = new QVIFilters
{
IdentifiedSavings = 0,
QVICases = 0,
BreakdownIds = new List<string>(),
QualityVariationEventIds = new List<string>(),
ViewVisible = true,
ExcludeInitiatives = false,
OpportunitySearch = "",
ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345")
};
try
{
// act
var taskResult =
await variationOpportunityService.ExportAsync(new SortOptions(), filters, cancellationToken);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNull();
}
else
{
taskResult.Should().NotBeNull()
.And.BeOfType<XLWorkbook>();
var wb = taskResult;
wb.Worksheets.Should().HaveCountGreaterThan(0);
var ws = wb.Worksheet("Sheet1");
ws.ColumnCount().Should().BeGreaterThan(0);
ws.RowCount().Should().BeGreaterThan(0);
}
}
catch (TypeInitializationException tie)
{
tie.Should().BeOfType<TypeInitializationException>();
}
catch (AssertionException ae)
{
ae.Should().BeOfType<AssertionException>();
}
catch (ArgumentNullException arg)
{
arg.Should().BeOfType<ArgumentNullException>();
}
catch (Exception e)
{
e.Should().BeOfType<OperationCanceledException>();
}
}
[Test]
public async Task TestSetHidden()
{
// arrange
var framework = new JazzEntityFrameworkFactory();
await framework.CreateDbContextAsync(CancellationToken.None);
var opportunities = framework.QVIOpportunities;
var opportunity = opportunities.First(vo => !vo.IsHidden);
var isHidden = opportunity.IsHidden;
var service = new QVIOpportunityService(framework, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
// act
await service.SetHiddenAsync(opportunity.OpportunityGuid, !isHidden, CancellationToken.None);
// assert
var result = await service.GetById(opportunity.OpportunityGuid, CancellationToken.None);
result.IsHidden.Should().Be(!isHidden);
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworksWithCancellation))]
public async Task TestGetFilterOptionsAsync(JazzEntityFrameworkFactory jazzEntityFrameworkFactory, CancellationToken cancellationToken)
{
// arrange
var qualityVariationItemOpportunityService = new QVIOpportunityService(jazzEntityFrameworkFactory, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
try
{
// act
var taskResult = await qualityVariationItemOpportunityService
.GetFilterOptionsAsync(new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345"), cancellationToken);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNull();
return;
}
taskResult.Should()
.BeOfType<QVIFilterOptions>()
.And.NotBeNull();
taskResult.Breakdowns.Should().AllBeOfType<FilterMember>().And.NotBeNullOrEmpty()
.And.NotContain(cd => string.IsNullOrEmpty(cd.Id))
.And.NotContain(cd => string.IsNullOrEmpty(cd.Text));
}
catch (NotImplementedException nie)
{
nie.Should().BeOfType<NotImplementedException>();
}
catch (Exception e)
{
e.Should().BeOfType<OperationCanceledException>();
}
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworksWithCancellation))]
public async Task TestSetHiddenAsync(JazzEntityFrameworkFactory jazzEntityFrameworkFactory, CancellationToken cancellationToken)
{
// arrange
var qualityVariationItemOpportunityService = new QVIOpportunityService(jazzEntityFrameworkFactory, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
try
{
var opportunities = qualityVariationItemOpportunityService.GetAllAsync(cancellationToken).Result;
var opportunity = opportunities.FirstOrDefault(o => o.IsHidden);
if (opportunity == null) return;
var isHidden = opportunity.IsHidden;
//act
await qualityVariationItemOpportunityService.SetHiddenAsync(opportunity.OpportunityGuid, !isHidden,
cancellationToken);
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName)) return;
var result = qualityVariationItemOpportunityService.GetById(opportunity.OpportunityGuid, cancellationToken).Result;
result.IsHidden.Should().Be(!isHidden);
}
catch (Exception e)
{
switch (e.GetType().Name)
{
case "AggregateException":
case "OperationCanceledException":
return;
}
e.Should().NotBeOfType<Exception>();
}
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworksWithCancellation))]
public async Task TestSetHiddenAsync_NoOpportunity(JazzEntityFrameworkFactory jazzEntityFrameworkFactory, CancellationToken cancellationToken)
{
// arrange
var opportunity = jazzEntityFrameworkFactory.QVIOpportunities.FirstOrDefault(o => o.IsHidden);
if (opportunity == null) return;
var isHidden = opportunity.IsHidden;
var qualityVariationItemOpportunityService = new QVIOpportunityService(jazzEntityFrameworkFactory, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
try
{
// act
await qualityVariationItemOpportunityService.SetHiddenAsync(Guid.Empty, !isHidden,
cancellationToken);
}
catch (Exception e)
{
e.Should().BeOfType<OperationCanceledException>();
}
}
[Test]
public async Task TestSetNote()
{
// arrange
var framework = new JazzEntityFrameworkFactory();
await framework.CreateDbContextAsync(CancellationToken.None);
var opportunities = framework.QVIOpportunities;
var opportunity = opportunities.First(vo => string.IsNullOrEmpty(vo.Note));
var note = opportunity.Note;
var expected = "Now is the time for all good engineers to write great code!";
var service = new QVIOpportunityService(framework, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
// act
await service.SetNoteAsync(opportunity.OpportunityGuid, expected, CancellationToken.None);
// assert
var result = await service.GetById(opportunity.OpportunityGuid, CancellationToken.None);
result.Note.Should().NotBeNullOrEmpty()
.And.NotBe(note)
.And.Be(expected);
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworksWithCancellation))]
public async Task TestSetNoteAsync(JazzEntityFrameworkFactory jazzEntityFrameworkFactory, CancellationToken cancellationToken)
{
// arrange
var qualityVariationItemOpportunityService = new QVIOpportunityService(jazzEntityFrameworkFactory, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
try
{
var opportunities = qualityVariationItemOpportunityService.GetAllAsync(cancellationToken).Result;
var opportunity = opportunities.FirstOrDefault(o => o.Note == string.Empty);
if (opportunity == null) return;
var note = "new test note";
// act
await qualityVariationItemOpportunityService.SetNoteAsync(opportunity.OpportunityGuid, note,
CancellationToken.None);
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName)) return;
var result = qualityVariationItemOpportunityService.GetById(opportunity.OpportunityGuid, cancellationToken).Result;
result.Note.Should().Be(note);
// assert
}
catch (Exception e)
{
switch (e.GetType().Name)
{
case "AggregateException":
case "OperationCanceledException":
return;
}
e.Should().NotBeOfType<Exception>();
}
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworksWithCancellation))]
public async Task TestSetNoteAsync_NoOpportunity(JazzEntityFrameworkFactory jazzEntityFrameworkFactory, CancellationToken cancellationToken)
{
// arrange
var opportunity = jazzEntityFrameworkFactory.QVIOpportunities.FirstOrDefault(o => o.Note == string.Empty);
if (opportunity == null) return;
var note = "new test note";
var qualityVariationItemOpportunityService = new QVIOpportunityService(jazzEntityFrameworkFactory, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
try
{
// act
await qualityVariationItemOpportunityService.SetNoteAsync(Guid.Empty, note, cancellationToken);
// assert
}
catch (Exception e)
{
e.Should().BeOfType<OperationCanceledException>();
}
}
#region JazzDbService Tests
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworks))]
public async Task TestGetAllAsync(JazzEntityFrameworkFactory jazzEntityFrameworkFactory)
{
// arrange
var qualityVariationItemOpportunityService = new QVIOpportunityService(jazzEntityFrameworkFactory, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
// act
var taskResult = await qualityVariationItemOpportunityService.GetAllAsync(CancellationToken.None);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNullOrEmpty();
}
else
{
taskResult.Should().NotBeNullOrEmpty();
}
}
[Test, Ignore("Broken due to removal of Key from VariationCaseType")]
public async Task TestGetAllAsync_Filtered()
{
// arrange
var factory = new JazzEntityFrameworkFactory();
var filters = factory.QVIOpportunities;
var qualityVariationItemOpportunityService = new QVIOpportunityService(factory, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
// act
var taskResult = await qualityVariationItemOpportunityService.GetAllAsync(CancellationToken.None);
// assert
taskResult.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIOpportunity>()
.And.HaveCountGreaterThan(0)
.And.NotContain(o => string.IsNullOrEmpty(o.ToString()))
.And.Contain(o => filters.Select(f => f.OpportunityGuid).Contains(o.OpportunityGuid))
.And.Contain(o => filters.Select(f => f.BreakdownName).Contains(o.BreakdownName))
.And.Contain(o => filters.Select(f => f.ConfigurationGuid).Contains(o.ConfigurationGuid));
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworks))]
public async Task TestGetById(JazzEntityFrameworkFactory jazzEntityFrameworkFactory)
{
// arrange
var qualityVariationItemOpportunityService = new QVIOpportunityService(jazzEntityFrameworkFactory, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
// act
var tempResult = await qualityVariationItemOpportunityService.GetAllAsync(CancellationToken.None);
var taskResult =
await qualityVariationItemOpportunityService.GetById(tempResult.FirstOrDefault()?.OpportunityGuid ?? Guid.Empty, CancellationToken.None);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNull();
}
else
{
taskResult.Should().NotBeNull()
.And.BeOfType<QVIOpportunity>();
}
}
[TestCaseSource(typeof(JazzEntityFrameworkFactory), nameof(JazzEntityFrameworkFactory.GetFrameworks))]
public async Task TestGetByIds(JazzEntityFrameworkFactory jazzEntityFrameworkFactory)
{
// arrange
var qualityVariationItemOpportunityService = new QVIOpportunityService(jazzEntityFrameworkFactory, null, null, _initiativeService, _updateFactOpportunitySavingsService, _configurationService, _logger);
// act
var tempResult = await qualityVariationItemOpportunityService.GetAllAsync(CancellationToken.None);
var ids = tempResult.Select(o => o.OpportunityGuid);
var taskResult = await qualityVariationItemOpportunityService.GetByIds(ids, CancellationToken.None);
// assert
if (string.IsNullOrEmpty(jazzEntityFrameworkFactory.TestName))
{
taskResult.Should().BeNullOrEmpty();
}
else
{
taskResult.Should().NotBeNullOrEmpty()
.And.AllBeOfType<QVIOpportunity>();
}
}
#endregion
[TearDown]
public void TestTearDown()
{
// Method intentionally left empty.
}
#region TestCaseData
public static IEnumerable<TestCaseData> GetFilterData()
{
yield return new TestCaseData(new QVIFilters { ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") }).SetName("No Filters");
yield return new TestCaseData(new QVIFilters { ViewVisible = true, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") }).SetName("View Visible");
yield return new TestCaseData(new QVIFilters { ViewVisible = false, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") }).SetName("Not View Visible");
yield return new TestCaseData(new QVIFilters { IdentifiedSavings = 1999, ViewVisible = true, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") }).SetName(
"By Identified Savings");
yield return new TestCaseData(new QVIFilters { IdentifiedSavings = 999, ViewVisible = false, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") }).SetName(
"By Identified Savings Not ViewVisible");
yield return new TestCaseData(new QVIFilters { BreakdownIds = new[] { "1" }, ViewVisible = true, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") })
.SetName("By Breakdown");
yield return new TestCaseData(new QVIFilters { BreakdownIds = new[] { "2" }, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345"), ViewVisible = false })
.SetName("By Breakdown Not ViewVisible");
yield return new TestCaseData(new QVIFilters { QualityVariationEventIds = new[] { "1" }, ViewVisible = true, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") })
.SetName("By QualityVariationEvent");
yield return new TestCaseData(new QVIFilters { QualityVariationEventIds = new[] { "2" }, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345"), ViewVisible = false })
.SetName("By QualityVariationEvent Not ViewVisible");
yield return new TestCaseData(new QVIFilters { OpportunitySearch = "QV - 123", ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") }).SetName("Search By Id");
yield return new TestCaseData(new QVIFilters { ExcludeInitiatives = true, ConfigurationGuid = new Guid("e96abe3e-1526-43ca-815e-ee30c5b34345") }).SetName("Exclude Opportunities with Initiatives");
}
public static IEnumerable<TestCaseData> GetFrameworkWithFilterData()
{
var testCases = GetFilterData().ToList();
var jeffs = JazzEntityFrameworkFactory.GetFrameworksWithCancellation()
.Select(tcd => tcd.Arguments);
foreach (var tcd in jeffs)
{
var jeff = (JazzEntityFrameworkFactory)tcd[0];
var ct = (CancellationToken)tcd[1];
foreach (var testCase in testCases)
{
yield return new TestCaseData(jeff, testCase.Arguments.GetValue(0), ct)
.SetName($"{testCase.TestName} {(string.IsNullOrEmpty(jeff.TestName) ? "w/o Jeff" : "w/Jeff")}")
.SetCategory(jeff.TestName);
}
var serviceLineId = jeff.QVIOpportunities.FirstOrDefault(o => !o.IsHidden)?.BreakdownId ?? 0;
if (string.IsNullOrEmpty(jeff.TestName))
{
yield return new TestCaseData(jeff,
new QVIFilters { BreakdownIds = new[] { serviceLineId.ToString() }, ViewVisible = false }, ct)
.SetName("By Service Line Not ViewVisible w/o Jeff");
}
else
{
yield return new TestCaseData(jeff, ct, new QVIFilters { BreakdownIds = new[] { serviceLineId.ToString() }, ViewVisible = false })
.SetName("By Service Line Not ViewVisible w/Jeff")
.Ignore("This test is broken");
}
}
}
#endregion
}
}
@@ -0,0 +1,201 @@
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
using Strata.ContinuousImprovement.Biz.Configuration;
using Strata.ContinuousImprovement.Biz.DbContexts.Snowflake;
using Strata.ContinuousImprovement.Biz.QualityVariation.QVI;
using CIConfiguration = Strata.ContinuousImprovement.Biz.Configuration.Configuration;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Strata.ContinuousImprovement.Biz.Test.Unit.QualityVariation.QVI
{
[TestFixture, Category("Unit")]
public class NonQviSavingsServiceTest
{
private Mock<ISnowflakeDatabaseContext> _snowflakeDatabaseContextMock;
private Mock<IConfigurationService> _configurationServiceMock;
private Mock<ILogger<NonQviSavingsService>> _loggerMock;
private NonQviSavingsService _service;
[SetUp]
public void SetUp()
{
_snowflakeDatabaseContextMock = new Mock<ISnowflakeDatabaseContext>();
_configurationServiceMock = new Mock<IConfigurationService>();
_loggerMock = new Mock<ILogger<NonQviSavingsService>>();
_service = new NonQviSavingsService(
_snowflakeDatabaseContextMock.Object,
_configurationServiceMock.Object,
_loggerMock.Object);
}
[Test]
public async Task GetCaseTypeFamilyInfoAsync_WhenNoEntityIds_ReturnsEmpty()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration { EntityIdsCSV = string.Empty, SourceSystemIdsCSV = "1" });
var result = await _service.GetCaseTypeFamilyInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEmpty();
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<NonQviCaseTypeFamilyInfo>(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Never);
}
[Test]
public async Task GetCaseTypeFamilyInfoAsync_WhenNoSourceSystemIds_ReturnsEmpty()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration { EntityIdsCSV = "1", SourceSystemIdsCSV = string.Empty });
var result = await _service.GetCaseTypeFamilyInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEmpty();
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<NonQviCaseTypeFamilyInfo>(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Never);
}
[Test]
public async Task GetCaseTypeFamilyInfoAsync_WhenEntitiesExist_QueriesSnowflake()
{
var configurationGuid = Guid.NewGuid();
var expected = new[] { new NonQviCaseTypeFamilyInfo { CaseTypeFamilyId = 10, CaseCount = 3 } };
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration
{
EntityIdsCSV = "1",
SourceSystemIdsCSV = "1",
DepartmentRollupGlobalId = string.Empty,
QualityVariationEndDate = new DateTime(2024, 12, 31)
});
_snowflakeDatabaseContextMock
.Setup(s => s.QueryAsync<NonQviCaseTypeFamilyInfo>(
It.IsAny<string>(),
nameof(NonQviSavingsService.GetCaseTypeFamilyInfoAsync),
It.IsAny<object>(),
It.IsAny<TimeSpan>()))
.ReturnsAsync(expected);
var result = await _service.GetCaseTypeFamilyInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEquivalentTo(expected);
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<NonQviCaseTypeFamilyInfo>(
It.IsAny<string>(),
nameof(NonQviSavingsService.GetCaseTypeFamilyInfoAsync),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Once);
}
[Test]
public async Task GetDrgTypeInfoAsync_WhenNoEntityIds_ReturnsEmpty()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration { EntityIdsCSV = string.Empty, SourceSystemIdsCSV = "1" });
var result = await _service.GetDrgTypeInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEmpty();
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<NonQviDrgTypeInfo>(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Never);
}
[Test]
public async Task GetDrgTypeInfoAsync_WhenNoSourceSystemIds_ReturnsEmpty()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration { EntityIdsCSV = "1", SourceSystemIdsCSV = string.Empty });
var result = await _service.GetDrgTypeInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEmpty();
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<NonQviDrgTypeInfo>(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Never);
}
[Test]
public async Task GetDrgTypeInfoAsync_WhenEntitiesExist_QueriesSnowflake()
{
var configurationGuid = Guid.NewGuid();
var expected = new[] { new NonQviDrgTypeInfo { DrgType = "MS" } };
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration
{
EntityIdsCSV = "1",
SourceSystemIdsCSV = "1",
DepartmentRollupGlobalId = string.Empty,
QualityVariationEndDate = new DateTime(2024, 12, 31)
});
_snowflakeDatabaseContextMock
.Setup(s => s.QueryAsync<NonQviDrgTypeInfo>(
It.IsAny<string>(),
nameof(NonQviSavingsService.GetDrgTypeInfoAsync),
It.IsAny<object>(),
It.IsAny<TimeSpan>()))
.ReturnsAsync(expected);
var result = await _service.GetDrgTypeInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEquivalentTo(expected);
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<NonQviDrgTypeInfo>(
It.IsAny<string>(),
nameof(NonQviSavingsService.GetDrgTypeInfoAsync),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Once);
}
[Test]
public async Task GetDrgTypeInfoAsync_WhenConfigurationThrows_Rethrows()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ThrowsAsync(new InvalidOperationException("boom"));
var action = async () => await _service.GetDrgTypeInfoAsync(configurationGuid, true, CancellationToken.None);
await action.Should().ThrowAsync<InvalidOperationException>();
}
}
}
@@ -0,0 +1,96 @@
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
using Strata.ContinuousImprovement.Biz.Configuration;
using Strata.ContinuousImprovement.Biz.DbContexts;
using Strata.ContinuousImprovement.Biz.DbContexts.Snowflake;
using Strata.ContinuousImprovement.Biz.QualityVariation.QVI;
using Strata.SqlTools.Configuration.Common.AsyncFactory;
using CIConfiguration = Strata.ContinuousImprovement.Biz.Configuration.Configuration;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Strata.ContinuousImprovement.Biz.Test.Unit.QualityVariation.QVI
{
[TestFixture, Category("Unit")]
public class QviEncounterServiceTest
{
private Mock<ISnowflakeDatabaseContext> _snowflakeDatabaseContextMock;
private Mock<IConfigurationService> _configurationServiceMock;
private Mock<IAsyncDbContextFactory<JazzDbContext>> _dbContextFactoryMock;
private Mock<ILogger<QviEncounterService>> _loggerMock;
private QviEncounterService _service;
[SetUp]
public void SetUp()
{
_snowflakeDatabaseContextMock = new Mock<ISnowflakeDatabaseContext>();
_configurationServiceMock = new Mock<IConfigurationService>();
_dbContextFactoryMock = new Mock<IAsyncDbContextFactory<JazzDbContext>>();
_loggerMock = new Mock<ILogger<QviEncounterService>>();
_service = new QviEncounterService(
_snowflakeDatabaseContextMock.Object,
_configurationServiceMock.Object,
_dbContextFactoryMock.Object,
_loggerMock.Object);
}
[Test]
public async Task GetEncounterInfoAsync_WhenNoEntityIds_ReturnsEmptyAndSkipsDatabase()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration { EntityIdsCSV = string.Empty, SourceSystemIdsCSV = "1" });
var result = await _service.GetEncounterInfoAsync(configurationGuid, DateTime.UtcNow, DateTime.UtcNow, CancellationToken.None);
result.Should().BeEmpty();
_dbContextFactoryMock.Verify(f => f.CreateDbContextAsync(It.IsAny<CancellationToken>()), Times.Never);
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<EncounterInfo>(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Never);
}
[Test]
public async Task GetEncounterInfoAsync_WhenNoSourceSystemIds_ReturnsEmptyAndSkipsDatabase()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration { EntityIdsCSV = "1", SourceSystemIdsCSV = string.Empty });
var result = await _service.GetEncounterInfoAsync(configurationGuid, DateTime.UtcNow, DateTime.UtcNow, CancellationToken.None);
result.Should().BeEmpty();
_dbContextFactoryMock.Verify(f => f.CreateDbContextAsync(It.IsAny<CancellationToken>()), Times.Never);
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<EncounterInfo>(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Never);
}
[Test]
public async Task GetEncounterInfoAsync_WhenConfigurationThrows_Rethrows()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ThrowsAsync(new InvalidOperationException("boom"));
var action = async () => await _service.GetEncounterInfoAsync(configurationGuid, DateTime.UtcNow, DateTime.UtcNow, CancellationToken.None);
await action.Should().ThrowAsync<InvalidOperationException>();
}
}
}
@@ -0,0 +1,265 @@
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
using Strata.ContinuousImprovement.Biz.Configuration;
using Strata.ContinuousImprovement.Biz.DbContexts.Snowflake;
using Strata.ContinuousImprovement.Biz.QualityVariation.QVI;
using CIConfiguration = Strata.ContinuousImprovement.Biz.Configuration.Configuration;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Strata.ContinuousImprovement.Biz.Test.Unit.QualityVariation.QVI
{
[TestFixture, Category("Unit")]
public class QviLineItemSavingsServiceTest
{
private Mock<ISnowflakeDatabaseContext> _snowflakeDatabaseContextMock;
private Mock<IConfigurationService> _configurationServiceMock;
private Mock<ILogger<QviLineItemSavingsService>> _loggerMock;
private QviLineItemSavingsService _service;
[SetUp]
public void SetUp()
{
_snowflakeDatabaseContextMock = new Mock<ISnowflakeDatabaseContext>();
_configurationServiceMock = new Mock<IConfigurationService>();
_loggerMock = new Mock<ILogger<QviLineItemSavingsService>>();
_service = new QviLineItemSavingsService(
_snowflakeDatabaseContextMock.Object,
_configurationServiceMock.Object,
_loggerMock.Object);
}
[Test]
public async Task GetCaseTypeFamilyInfoAsync_WhenNoEntityIds_ReturnsEmpty()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration { EntityIdsCSV = string.Empty, SourceSystemIdsCSV = "1" });
var result = await _service.GetCaseTypeFamilyInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEmpty();
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<QviLineItemCaseTypeFamilyInfo>(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Never);
}
[Test]
public async Task GetCaseTypeFamilyInfoAsync_WhenNoSourceSystemIds_ReturnsEmpty()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration { EntityIdsCSV = "1", SourceSystemIdsCSV = string.Empty });
var result = await _service.GetCaseTypeFamilyInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEmpty();
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<QviLineItemCaseTypeFamilyInfo>(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Never);
}
[Test]
public async Task GetCaseTypeFamilyInfoAsync_WhenEntitiesExist_QueriesSnowflake()
{
var configurationGuid = Guid.NewGuid();
var expected = new[] { new QviLineItemCaseTypeFamilyInfo { QualityVariationEventId = 42, CaseTypeFamilyId = 7 } };
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration
{
EntityIdsCSV = "1",
SourceSystemIdsCSV = "1",
DepartmentRollupGlobalId = string.Empty,
QualityVariationEndDate = new DateTime(2024, 12, 31)
});
_snowflakeDatabaseContextMock
.Setup(s => s.QueryAsync<QviLineItemCaseTypeFamilyInfo>(
It.IsAny<string>(),
nameof(QviLineItemSavingsService.GetCaseTypeFamilyInfoAsync),
It.IsAny<object>(),
It.IsAny<TimeSpan>()))
.ReturnsAsync(expected);
var result = await _service.GetCaseTypeFamilyInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEquivalentTo(expected);
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<QviLineItemCaseTypeFamilyInfo>(
It.IsAny<string>(),
nameof(QviLineItemSavingsService.GetCaseTypeFamilyInfoAsync),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Once);
}
[Test]
public async Task GetDrgTypeInfoAsync_WhenNoEntityIds_ReturnsEmpty()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration { EntityIdsCSV = string.Empty, SourceSystemIdsCSV = "1" });
var result = await _service.GetDrgTypeInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEmpty();
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<QviLineItemDrgTypeInfo>(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Never);
}
[Test]
public async Task GetDrgTypeInfoAsync_WhenNoSourceSystemIds_ReturnsEmpty()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration { EntityIdsCSV = "1", SourceSystemIdsCSV = string.Empty });
var result = await _service.GetDrgTypeInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEmpty();
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<QviLineItemDrgTypeInfo>(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Never);
}
[Test]
public async Task GetDrgTypeInfoAsync_WhenEntitiesExist_QueriesSnowflake()
{
var configurationGuid = Guid.NewGuid();
var expected = new[] { new QviLineItemDrgTypeInfo { DrgType = "APR" } };
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration
{
EntityIdsCSV = "1",
SourceSystemIdsCSV = "1",
DepartmentRollupGlobalId = string.Empty,
QualityVariationEndDate = new DateTime(2024, 12, 31)
});
_snowflakeDatabaseContextMock
.Setup(s => s.QueryAsync<QviLineItemDrgTypeInfo>(
It.IsAny<string>(),
nameof(QviLineItemSavingsService.GetDrgTypeInfoAsync),
It.IsAny<object>(),
It.IsAny<TimeSpan>()))
.ReturnsAsync(expected);
var result = await _service.GetDrgTypeInfoAsync(configurationGuid, true, CancellationToken.None);
result.Should().BeEquivalentTo(expected);
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<QviLineItemDrgTypeInfo>(
It.IsAny<string>(),
nameof(QviLineItemSavingsService.GetDrgTypeInfoAsync),
It.IsAny<object>(),
It.IsAny<TimeSpan>()),
Times.Once);
}
[Test]
public async Task GetEncounterSavingInfoAsync_UsesConfigurationGuidParameter()
{
var configurationGuid = Guid.NewGuid();
var expected = new[] { new QviLineItemEncounterSavingInfo { EncounterRecordNumber = "enc-1" } };
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration());
_snowflakeDatabaseContextMock
.Setup(s => s.QueryAsync<QviLineItemEncounterSavingInfo>(
It.IsAny<string>(),
nameof(QviLineItemSavingsService.GetEncounterSavingInfoAsync),
It.IsAny<object>(),
It.IsAny<TimeSpan>()))
.ReturnsAsync(expected);
var result = await _service.GetEncounterSavingInfoAsync(configurationGuid, null, null, CancellationToken.None);
result.Should().BeEquivalentTo(expected);
_snowflakeDatabaseContextMock.Verify(
s => s.QueryAsync<QviLineItemEncounterSavingInfo>(
It.IsAny<string>(),
nameof(QviLineItemSavingsService.GetEncounterSavingInfoAsync),
It.Is<object>(o =>
o.GetType().GetProperty("ConfigurationGUID") != null &&
(Guid)o.GetType().GetProperty("ConfigurationGUID").GetValue(o)! == configurationGuid),
It.IsAny<TimeSpan>()),
Times.Once);
}
[Test]
public async Task GetEncounterSavingInfoAsync_WhenOpportunityGuidAndIsBaselineProvided_FiltersQuery()
{
var configurationGuid = Guid.NewGuid();
var opportunityGuid = Guid.NewGuid();
var expected = new[] { new QviLineItemEncounterSavingInfo { EncounterRecordNumber = "enc-1" } };
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration());
_snowflakeDatabaseContextMock
.Setup(s => s.QueryAsync<QviLineItemEncounterSavingInfo>(
It.Is<string>(q => q.Contains(":OpportunityGUID") && q.Contains(":IsBaseline")),
nameof(QviLineItemSavingsService.GetEncounterSavingInfoAsync),
It.IsAny<object>(),
It.IsAny<TimeSpan>()))
.ReturnsAsync(expected);
var result = await _service.GetEncounterSavingInfoAsync(configurationGuid, opportunityGuid, true, CancellationToken.None);
result.Should().BeEquivalentTo(expected);
}
[Test]
public async Task GetEncounterSavingInfoAsync_WhenSnowflakeThrows_Rethrows()
{
var configurationGuid = Guid.NewGuid();
_configurationServiceMock
.Setup(s => s.GetConfigurationAsync(configurationGuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new CIConfiguration());
_snowflakeDatabaseContextMock
.Setup(s => s.QueryAsync<QviLineItemEncounterSavingInfo>(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<TimeSpan>()))
.ThrowsAsync(new InvalidOperationException("boom"));
var action = async () => await _service.GetEncounterSavingInfoAsync(configurationGuid, null, null, CancellationToken.None);
await action.Should().ThrowAsync<InvalidOperationException>();
}
}
}