Files

222 lines
12 KiB
C#

using ClosedXML.Excel;
using Microsoft.Extensions.Logging;
using Moq;
using MoreLinq;
using NUnit.Framework;
using Strata.ApiLib.Standard.Models;
using Strata.ContinuousImprovement.Api.Controllers;
using Strata.ContinuousImprovement.Biz.All;
using Strata.ContinuousImprovement.Biz.All.Opportunities;
using Strata.ContinuousImprovement.Biz.All.Opportunities.Filters;
using Strata.ContinuousImprovement.Biz.Export;
using Strata.ContinuousImprovement.Biz.Filter;
using Strata.ContinuousImprovement.Biz.Generics;
using Strata.ContinuousImprovement.Biz.Pagination;
using Strata.ContinuousImprovement.Biz.Test.Unit.Utilities;
using Strata.ContinuousImprovement.JazzEntityFrameworkStub;
using Strata.FeatureFlags.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Strata.ContinuousImprovement.Api.Test.Unit.Controllers
{
[TestFixture, Category("Unit"), Category("Controller")]
public class AllOpportunityControllerTests
{
public const string ConfigurationGuid = "aa4cba4f-2506-462c-8e34-c45b21653988";
[TestCaseSource(nameof(GetOpportunityTestCases))]
public async Task GetOpportunityTest(bool featureFlagSet, bool featureFlagIsOn, bool isSdtEmployee = true)
{
var result = await GetPagedApiResponse(featureFlagSet);
var service = await GetAllOpportunityService(result);
var claimsPrincipalAccessor = TestUtilities.GetClaimsPrincipalAccessor(isSdtEmployee: isSdtEmployee);
var featureFlagServiceClient = featureFlagSet
? TestUtilities.GetFeatureFlagServiceClient("ciflexibleexplorationenabled", featureFlagIsOn)
: Mock.Of<IFeatureFlagServiceClient>();
var controller = new AllOpportunitiesController(service, claimsPrincipalAccessor,
featureFlagServiceClient,
Mock.Of<ILogger<AllOpportunitiesController>>());
var pagedResponse = await controller.GetOpportunities(new AllOpportunityLoadOptions
{
PagingOptions = new PagingOptions { First = 0, Rows = 20, SortField = "IdentifiedSavings", SortOrder = SortOrder.Desc },
Filters = new AllFilters
{
ConfigurationGuid = new Guid(ConfigurationGuid)
}
}, CancellationToken.None);
Assert.That(result, Is.SameAs(pagedResponse));
}
public static IEnumerable<TestCaseData> GetOpportunityTestCases()
{
yield return new TestCaseData(true, false, true)
.SetName(nameof(GetOpportunityTest) + " FeatureFlag Off SdtEmployee");
yield return new TestCaseData(true, true, true)
.SetName(nameof(GetOpportunityTest) + " FeatureFlag On SdtEmployee");
yield return new TestCaseData(true, false, false)
.SetName(nameof(GetOpportunityTest) + " FeatureFlag Off Not SdtEmployee");
yield return new TestCaseData(true, true, false)
.SetName(nameof(GetOpportunityTest) + " FeatureFlag On Not SdtEmployee");
yield return new TestCaseData(false, false, true)
.SetName(nameof(GetOpportunityTest) + " No FeatureFlag Off SdtEmployee");
yield return new TestCaseData(false, true, true)
.SetName(nameof(GetOpportunityTest) + " No FeatureFlag On SdtEmployee");
yield return new TestCaseData(false, false, false)
.SetName(nameof(GetOpportunityTest) + " No FeatureFlag Off Not SdtEmployee");
yield return new TestCaseData(false, true, false)
.SetName(nameof(GetOpportunityTest) + " No FeatureFlag On Not SdtEmployee");
}
[TestCase(false)]
[TestCase(true)]
public async Task GetNameIsValidTest(bool isValid)
{
var result = await GetPagedApiResponse();
var service = await GetAllOpportunityService(result);
var claimsPrincipalAccessor = TestUtilities.GetClaimsPrincipalAccessor();
var firstRow = result.Data.First();
var validateName = new ValidateName
{
ConfigurationGuid = firstRow.ConfigurationGuid,
OpportunityGuid = isValid ? Guid.NewGuid() : firstRow.OpportunityGuid,
Name = firstRow.Name,
OpportunityType = firstRow.OpportunityType
};
var controller = new AllOpportunitiesController(service, claimsPrincipalAccessor,
Mock.Of<IFeatureFlagServiceClient>(),
Mock.Of<ILogger<AllOpportunitiesController>>());
var isNameValid = await controller.IsNameValid(validateName, CancellationToken.None);
Assert.That(isValid, Is.EqualTo(isNameValid));
}
[TestCase(true)]
[TestCase(false)]
public async Task GetFilterOptionsTest(bool isSdtEmployee)
{
var result = await GetPagedApiResponse();
var service = await GetAllOpportunityService(result);
var claimsPrincipalAccessor = TestUtilities.GetClaimsPrincipalAccessor(isSdtEmployee: isSdtEmployee);
var controller = new AllOpportunitiesController(service, claimsPrincipalAccessor,
Mock.Of<IFeatureFlagServiceClient>(),
Mock.Of<ILogger<AllOpportunitiesController>>());
var filterOptions = new AllFilterOptions
{
OpportunityTypes = Enum.GetValues<OpportunityTypes>()
.Where(ot => isSdtEmployee || ot != OpportunityTypes.Blank)
.Select(ot => new FilterMember { Id = $"{(int)ot}", Text = ot.OpportunityTypeName() })
};
var options = await controller.GetFilterOptionsAsync(result.Data.First().ConfigurationGuid, CancellationToken.None);
filterOptions.OpportunityTypes
.ForEach(ot => Assert.That(options.OpportunityTypes.Any(x => x.Id == ot.Id && x.Text == ot.Text), Is.True));
}
[Test, Ignore("Ignoring because we don't have generic GetById endpoint to use here.")]
public async Task SetHiddenAsyncTest()
{
var result = await GetPagedApiResponse();
var service = await GetAllOpportunityService(result);
var claimsPrincipalAccessor = TestUtilities.GetClaimsPrincipalAccessor();
var controller = new AllOpportunitiesController(service, claimsPrincipalAccessor,
Mock.Of<IFeatureFlagServiceClient>(),
Mock.Of<ILogger<AllOpportunitiesController>>());
var firstRow = result.Data.First(row => row.OpportunityType == (int)OpportunityTypes.Variation);
await controller.SetHiddenAsync(firstRow.OpportunityGuid, !firstRow.IsHidden, CancellationToken.None);
}
public async Task ExcelExportText()
{
var result = await GetPagedApiResponse();
var service = await GetAllOpportunityService(result);
var claimsPrincipalAccessor = TestUtilities.GetClaimsPrincipalAccessor();
var controller = new AllOpportunitiesController(service, claimsPrincipalAccessor,
Mock.Of<IFeatureFlagServiceClient>(),
Mock.Of<ILogger<AllOpportunitiesController>>());
var export = await controller.Export(new AllOpportunityExportOptions
{
SortOptions = new SortOptions(),
Filters = new AllFilters()
}, CancellationToken.None);
Assert.That(export, Is.AssignableFrom<ExcelContentResult>());
var workbook = ((ExcelContentResult)export).Workbook;
var filename = ((ExcelContentResult)export).FileName;
Assert.Multiple(() =>
{
Assert.That(workbook.Worksheets.First().Rows().Count(), Is.GreaterThan(result.Data.Count()));
Assert.That(filename, Is.Not.Null);
Assert.That(filename, Is.Not.Empty);
});
}
private async Task<PagedApiResponse<AllOpportunity>> GetPagedApiResponse(bool withExplorationOpportunities = true)
{
var jeff = new JazzEntityFrameworkFactory();
var dbContext = await jeff.CreateDbContextAsync(nameof(AllOpportunityControllerTests), CancellationToken.None);
var result = new PagedApiResponse<AllOpportunity>
{
Data = withExplorationOpportunities
? dbContext.AllOpportunities
: dbContext.AllOpportunities.Where(opp => opp.OpportunityType != (int)OpportunityTypes.Blank),
PagingInfo = new PagingInfo
{
ResultsPerPage = 20,
TotalNumberOfResults = dbContext.AllOpportunities.Count(),
TotalPages = dbContext.AllOpportunities.Count() / 20,
PageNumber = 1
}
};
return result;
}
private async Task<IAllOpportunityService> GetAllOpportunityService(PagedApiResponse<AllOpportunity> pagedApiResponse = null)
{
var jeff = new JazzEntityFrameworkFactory();
var dbContext = await jeff.CreateDbContextAsync(nameof(AllOpportunityControllerTests), CancellationToken.None);
var service = Mock.Of<IAllOpportunityService>();
Mock.Get(service)
.Setup(s => s.GetPagedAsync(It.IsAny<PagingOptions>(), It.IsAny<IFilters<AllOpportunity>>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(pagedApiResponse ?? await GetPagedApiResponse()));
Mock.Get(service)
.Setup(s => s.NameIsValid(It.IsAny<Guid>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<Guid?>(), It.IsAny<CancellationToken>()))
.Returns<Guid, int, string, Guid?, CancellationToken>((config, oppType, name, oppGuid, token)
=> Task.FromResult(!dbContext.AllOpportunities.Any(opp
=> opp.ConfigurationGuid == config
&& opp.OpportunityType == oppType
&& opp.OpportunityGuid == oppGuid
&& opp.Name.Equals(name, StringComparison.CurrentCultureIgnoreCase))));
var filterOptions = new AllFilterOptions
{
OpportunityTypes = Enum.GetValues<OpportunityTypes>()
.Select(ot => new FilterMember { Id = $"{(int)ot}", Text = ot.OpportunityTypeName() })
};
Mock.Get(service)
.Setup(s => s.GetFilterOptionsAsync(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.Returns<Guid, CancellationToken>((config, token) => Task.FromResult(filterOptions));
var exportOptions = new ExportOptions() { EmptyMessage = "No Opportunities" };
// configure column formats
exportOptions.AddColumnOptions("Identified Savings", "Currency2Dec");
exportOptions.AddColumnOptions("Is Hidden", "\"Yes\";-;\"No\"");
var xlWorkbook = (IXLWorkbook)ExportUtils.CreateExcelWorkbook(dbContext.AllOpportunities, exportOptions);
Mock.Get(service)
.Setup(s => s.ExportAsync(It.IsAny<SortOptions>(), It.IsAny<AllFilters>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(xlWorkbook));
Mock.Get(service)
.Setup(s => s.SetHiddenAsync(It.IsAny<Guid>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()))
.Returns(Task.CompletedTask);
Mock.Get(service)
.Setup(s => s.SetNoteAsync(It.IsAny<Guid>(), It.IsAny<string>(), It.IsAny<CancellationToken>()))
.Returns(Task.CompletedTask);
Mock.Get(service)
.Setup(s => s.GetById(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.Returns<Guid, CancellationToken>((oppGuid, token) => Task.FromResult(dbContext.AllOpportunities.FirstOrDefault(opp => opp.OpportunityGuid == oppGuid)));
return service;
}
}
}