public async Task GetFundingStreams_GivenNullOrEmptyFundingStreamsReturned_LogsAndReturnsOKWithEmptyList() { // Arrange ILogger logger = CreateLogger(); IEnumerable <FundingStream> fundingStreams = null; ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetFundingStreams() .Returns(fundingStreams); IFundingService fundingService = CreateService(logger: logger, specificationsRepository: specificationsRepository); // Act IActionResult result = await fundingService.GetFundingStreams(); // Assert result .Should() .BeOfType <OkObjectResult>(); OkObjectResult objectResult = result as OkObjectResult; IEnumerable <FundingStream> values = objectResult.Value as IEnumerable <FundingStream>; values .Should() .NotBeNull(); logger .Received(1) .Error(Arg.Is("No funding streams were returned")); }
private async Task <IEnumerable <FundingStream> > GetAllFundingStreams() { IEnumerable <FundingStream> allFundingStreams = await _specificationsRepository.GetFundingStreams(); if (allFundingStreams.IsNullOrEmpty()) { throw new NonRetriableException("Failed to get all funding streams"); } return(allFundingStreams); }
public void ValidateWithSpecificationAndFundingStreams_ValidatesAsExpected(CalculationCreateModel model, Specification specification, IEnumerable <FundingStream> fundingStreams, bool expectedResult, IEnumerable <string> expectedErrors) { //Arrange ISpecificationsRepository specsRepo = CreateSpecificationsRepository(false); specsRepo .GetSpecificationById(specificationId) .Returns(specification); specsRepo .GetFundingStreams() .Returns(fundingStreams); CalculationCreateModelValidator validator = CreateValidator(specsRepo); //Act ValidationResult result = validator.Validate(model); //Assert result .IsValid .Should() .Be(expectedResult); foreach (var error in expectedErrors) { result .Errors .Select(e => e.ErrorMessage) .Distinct() .Count(e => e == error) .Should() .Be(1, $"Expected to find error message '{error}'"); } result .Errors .Count .Should() .Be(expectedErrors.Count()); }
public void ValidateWithSpecificationAndFundingStream_ValidatesAsExpected(CalculationEditModel calculationEditModel, Specification specification, IEnumerable <FundingStream> fundingStreams, bool expectedResult, IEnumerable <string> expectedErrors) { //Arrange ISpecificationsRepository specsRepo = CreateSpecificationsRepository(false); specsRepo .GetSpecificationById(specificationId) .Returns(specification); specsRepo .GetFundingStreams() .Returns(fundingStreams); CalculationEditModelValidator validator = CreateValidator(specsRepo); // Act ValidationResult result = validator.Validate(calculationEditModel); // Assert result .IsValid .Should() .Be(expectedResult); result .Errors .Count .Should() .Be(expectedErrors.Count()); foreach (string error in expectedErrors) { result .Errors .Count(e => e.ErrorMessage == error) .Should() .Be(1, $"Error message collection should have included '{error}'"); } }
public async Task <IActionResult> GetFundingStreams() { IEnumerable <FundingStream> fundingStreams = await _cacheProvider.GetAsync <FundingStream[]>(CacheKeys.AllFundingStreams); if (fundingStreams.IsNullOrEmpty()) { fundingStreams = await _specificationsRepository.GetFundingStreams(); if (fundingStreams.IsNullOrEmpty()) { _logger.Error("No funding streams were returned"); fundingStreams = new FundingStream[0]; } await _cacheProvider.SetAsync <FundingStream[]>(CacheKeys.AllFundingStreams, fundingStreams.ToArray()); } return(new OkObjectResult(fundingStreams)); }
public async Task GetFundingStreams_GivenFundingStreamsReturned_ReturnsOKWithResults() { // Arrange ILogger logger = CreateLogger(); IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream(), new FundingStream() }; ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetFundingStreams() .Returns(fundingStreams); IFundingService fundingService = CreateService(logger: logger, specificationsRepository: specificationsRepository); // Act IActionResult result = await fundingService.GetFundingStreams(); // Assert result .Should() .BeOfType <OkObjectResult>(); OkObjectResult objectResult = result as OkObjectResult; IEnumerable <FundingStream> values = objectResult.Value as IEnumerable <FundingStream>; values .Count() .Should() .Be(2); }
public CalculationCreateModelValidator(ISpecificationsRepository specificationsRepository, ICalculationsRepository calculationsRepository) { Guard.ArgumentNotNull(specificationsRepository, nameof(specificationsRepository)); Guard.ArgumentNotNull(calculationsRepository, nameof(calculationsRepository)); _specificationsRepository = specificationsRepository; _calculationsRepository = calculationsRepository; RuleFor(model => model.Description) .NotEmpty() .WithMessage("You must give a description for the calculation"); RuleFor(model => model.SpecificationId) .NotEmpty() .WithMessage("Null or empty specification Id provided") .CustomAsync(async(name, context, cancellationToken) => { CalculationCreateModel model = context.ParentContext.InstanceToValidate as CalculationCreateModel; if (!string.IsNullOrWhiteSpace(model.SpecificationId)) { Specification specification = await _specificationsRepository.GetSpecificationById(model.SpecificationId); if (specification == null) { context.AddFailure("Specification not found"); return; } } }); RuleFor(model => model.PolicyId) .NotEmpty() .WithMessage("You must select a policy or a sub policy"); RuleFor(model => model.CalculationType) .IsInEnum() .WithMessage("You must specify a valid calculation type"); RuleFor(model => model.Name) .NotEmpty() .WithMessage("You must give a unique calculation name") .Custom((name, context) => { CalculationCreateModel model = context.ParentContext.InstanceToValidate as CalculationCreateModel; if (!_calculationsRepository.IsCalculationNameValid(model.SpecificationId, model.Name).Result) { context.AddFailure("Calculation with the same generated source code name already exists in this specification"); } }); RuleFor(model => model.AllocationLineId) .CustomAsync(async(name, context, cancellationToken) => { CalculationCreateModel model = context.ParentContext.InstanceToValidate as CalculationCreateModel; bool checkForDuplicateBaselineCalcs = false; bool requireAllocationLine = false; if (model.CalculationType == CalculationType.Baseline) { checkForDuplicateBaselineCalcs = true; requireAllocationLine = true; } if (model.CalculationType == CalculationType.Baseline || model.CalculationType == CalculationType.Number) { if (requireAllocationLine && string.IsNullOrWhiteSpace(model.AllocationLineId)) { context.AddFailure("Select an allocation line to create this calculation specification"); return; } if (!string.IsNullOrWhiteSpace(model.SpecificationId) && !string.IsNullOrWhiteSpace(model.AllocationLineId)) { IEnumerable <FundingStream> fundingStreams = await _specificationsRepository.GetFundingStreams(); if (fundingStreams == null) { context.AddFailure("Unable to query funding streams, result returned null"); return; } bool foundFundingStream = false; foreach (FundingStream fundingStream in fundingStreams) { foreach (AllocationLine allocationLine in fundingStream.AllocationLines) { if (allocationLine.Id == model.AllocationLineId) { foundFundingStream = true; break; } } if (foundFundingStream) { break; } } if (!foundFundingStream) { context.AddFailure("Unable to find Allocation Line with provided ID"); return; } if (checkForDuplicateBaselineCalcs) { Specification specification = await _specificationsRepository.GetSpecificationById(model.SpecificationId); if (specification == null) { context.AddFailure("Specification not found"); return; } bool existingBaselineSpecification = specification.Current.GetAllCalculations().Any(c => c.CalculationType == CalculationType.Baseline && string.Equals(c.AllocationLine?.Id, model.AllocationLineId, StringComparison.InvariantCultureIgnoreCase)); if (existingBaselineSpecification) { context.AddFailure("This specification already has an existing Baseline calculation associated with it. Please choose a different allocation line ID to create a Baseline calculation for."); return; } } } } }); }
public async Task EditSpecification_GivenChangesButFundingPeriodUnchanged_EnsuresCacheCorrectlyInvalidates() { //Arrange SpecificationEditModel specificationEditModel = new SpecificationEditModel { FundingPeriodId = "FP1", Name = "new spec name", FundingStreamIds = new[] { "fs11" } }; Period fundingPeriod = new Period { Id = "FP1", Name = "fp 1" }; IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream() }; string json = JsonConvert.SerializeObject(specificationEditModel); byte[] byteArray = Encoding.UTF8.GetBytes(json); MemoryStream stream = new MemoryStream(byteArray); HttpContext context = Substitute.For <HttpContext>(); HttpRequest request = Substitute.For <HttpRequest>(); IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "specificationId", new StringValues(SpecificationId) }, }); request .Query .Returns(queryStringValues); request .Body .Returns(stream); request .HttpContext .Returns(context); ILogger logger = CreateLogger(); Specification specification = CreateSpecification(); ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetSpecificationById(Arg.Is(SpecificationId)) .Returns(specification); specificationsRepository .GetPeriodById(Arg.Is(fundingPeriod.Id)) .Returns(fundingPeriod); specificationsRepository .GetFundingStreams(Arg.Any <Expression <Func <FundingStream, bool> > >()) .Returns(fundingStreams); specificationsRepository .UpdateSpecification(Arg.Any <Specification>()) .Returns(HttpStatusCode.OK); ICacheProvider cacheProvider = CreateCacheProvider(); SpecificationVersion newSpecVersion = specification.Current.Clone() as SpecificationVersion; IVersionRepository <SpecificationVersion> versionRepository = CreateVersionRepository(); versionRepository .CreateVersion(Arg.Any <SpecificationVersion>(), Arg.Any <SpecificationVersion>()) .Returns(newSpecVersion); SpecificationsService service = CreateService( logs: logger, specificationsRepository: specificationsRepository, cacheProvider: cacheProvider, specificationVersionRepository: versionRepository); //Act IActionResult result = await service.EditSpecification(request); //Arrange await cacheProvider .Received(1) .RemoveAsync <SpecificationSummary>(Arg.Is($"{CacheKeys.SpecificationSummaryById}{specification.Id}")); await cacheProvider .DidNotReceive() .RemoveAsync <List <SpecificationSummary> >(Arg.Is($"{CacheKeys.SpecificationSummariesByFundingPeriodId}fp1")); await versionRepository .Received(1) .SaveVersion(Arg.Is(newSpecVersion)); }
public async Task EditSpecification_GivenChangesAndSpecContainsPoliciesAndCalculations_UpdatesSearchAndSendsMessage() { //Arrange SpecificationEditModel specificationEditModel = new SpecificationEditModel { FundingPeriodId = "fp10", Name = "new spec name", FundingStreamIds = new[] { "fs11" } }; Period fundingPeriod = new Period { Id = "fp10", Name = "fp 10" }; IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream { AllocationLines = new List <AllocationLine> { new AllocationLine { Id = "al1", Name = "al2" } } } }; string json = JsonConvert.SerializeObject(specificationEditModel); byte[] byteArray = Encoding.UTF8.GetBytes(json); MemoryStream stream = new MemoryStream(byteArray); HttpContext context = Substitute.For <HttpContext>(); HttpRequest request = Substitute.For <HttpRequest>(); IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "specificationId", new StringValues(SpecificationId) }, }); request .Query .Returns(queryStringValues); request .Body .Returns(stream); request .HttpContext .Returns(context); ILogger logger = CreateLogger(); Specification specification = CreateSpecification(); specification .Current .Policies = new[] { new Policy { Calculations = new[] { new Calculation { AllocationLine = new AllocationLine { Id = "oldallocationlineid" } } } } }; ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetSpecificationById(Arg.Is(SpecificationId)) .Returns(specification); specificationsRepository .GetPeriodById(Arg.Is(fundingPeriod.Id)) .Returns(fundingPeriod); specificationsRepository .GetFundingStreams(Arg.Any <Expression <Func <FundingStream, bool> > >()) .Returns(fundingStreams); specificationsRepository .UpdateSpecification(Arg.Any <Specification>()) .Returns(HttpStatusCode.OK); ISearchRepository <SpecificationIndex> searchRepository = CreateSearchRepository(); ICacheProvider cacheProvider = CreateCacheProvider(); IMessengerService messengerService = CreateMessengerService(); SpecificationVersion newSpecVersion = specification.Current.Clone() as SpecificationVersion; newSpecVersion.Name = specificationEditModel.Name; newSpecVersion.FundingPeriod.Id = specificationEditModel.FundingPeriodId; newSpecVersion.FundingStreams = new[] { new FundingStream { Id = "fs11" } }; IVersionRepository <SpecificationVersion> versionRepository = CreateVersionRepository(); versionRepository .CreateVersion(Arg.Any <SpecificationVersion>(), Arg.Any <SpecificationVersion>()) .Returns(newSpecVersion); SpecificationsService service = CreateService( logs: logger, specificationsRepository: specificationsRepository, searchRepository: searchRepository, cacheProvider: cacheProvider, messengerService: messengerService, specificationVersionRepository: versionRepository); //Act IActionResult result = await service.EditSpecification(request); //Arrange await searchRepository .Received(1) .Index(Arg.Is <IEnumerable <SpecificationIndex> >( m => m.First().Id == SpecificationId && m.First().Name == "new spec name" && m.First().FundingPeriodId == "fp10" && m.First().FundingStreamIds.Count() == 1 )); await cacheProvider .Received(1) .RemoveAsync <SpecificationSummary>(Arg.Is($"{CacheKeys.SpecificationSummaryById}{specification.Id}")); await messengerService .Received(1) .SendToTopic(Arg.Is(ServiceBusConstants.TopicNames.EditSpecification), Arg.Is <SpecificationVersionComparisonModel>( m => m.Id == SpecificationId && m.Current.Name == "new spec name" && m.Previous.Name == "Spec name" ), Arg.Any <IDictionary <string, string> >(), Arg.Is(true)); await versionRepository .Received(1) .SaveVersion(Arg.Is(newSpecVersion)); }
public async Task EditSpecification_GivenFailsToUpdateCosomosWithBadRequest_ReturnsBadRequest() { //Arrange SpecificationEditModel specificationEditModel = new SpecificationEditModel { FundingPeriodId = "fp10" }; Period fundingPeriod = new Period { Id = "fp10", Name = "fp 10" }; IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream() }; string json = JsonConvert.SerializeObject(specificationEditModel); byte[] byteArray = Encoding.UTF8.GetBytes(json); MemoryStream stream = new MemoryStream(byteArray); HttpContext context = Substitute.For <HttpContext>(); HttpRequest request = Substitute.For <HttpRequest>(); IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "specificationId", new StringValues(SpecificationId) }, }); request .Query .Returns(queryStringValues); request .Body .Returns(stream); request .HttpContext .Returns(context); ILogger logger = CreateLogger(); Specification specification = CreateSpecification(); ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetSpecificationById(Arg.Is(SpecificationId)) .Returns(specification); specificationsRepository .GetPeriodById(Arg.Is(fundingPeriod.Id)) .Returns(fundingPeriod); specificationsRepository .GetFundingStreams(Arg.Any <Expression <Func <FundingStream, bool> > >()) .Returns(fundingStreams); specificationsRepository .UpdateSpecification(Arg.Any <Specification>()) .Returns(HttpStatusCode.BadRequest); SpecificationsService service = CreateService(logs: logger, specificationsRepository: specificationsRepository); //Act IActionResult result = await service.EditSpecification(request); //Arrange result .Should() .BeOfType <StatusCodeResult>() .Which .StatusCode .Should() .Be(400); }
public async Task EditSpecification_WhenIndexingReturnsErrors_ShouldThrowException() { //Arrange const string errorMessage = "Encountered error 802 code"; SpecificationEditModel specificationEditModel = new SpecificationEditModel { FundingPeriodId = "fp10", Name = "new spec name", FundingStreamIds = new[] { "fs11" } }; Period fundingPeriod = new Period { Id = "fp10", Name = "fp 10" }; IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream { AllocationLines = new List <AllocationLine> { new AllocationLine { Id = "al1", Name = "al2" } } } }; string json = JsonConvert.SerializeObject(specificationEditModel); byte[] byteArray = Encoding.UTF8.GetBytes(json); MemoryStream stream = new MemoryStream(byteArray); HttpContext context = Substitute.For <HttpContext>(); HttpRequest request = Substitute.For <HttpRequest>(); IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "specificationId", new StringValues(SpecificationId) }, }); request .Query .Returns(queryStringValues); request .Body .Returns(stream); request .HttpContext .Returns(context); ILogger logger = CreateLogger(); Specification specification = CreateSpecification(); ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetSpecificationById(Arg.Is(SpecificationId)) .Returns(specification); specificationsRepository .GetPeriodById(Arg.Is(fundingPeriod.Id)) .Returns(fundingPeriod); specificationsRepository .GetFundingStreams(Arg.Any <Expression <Func <FundingStream, bool> > >()) .Returns(fundingStreams); specificationsRepository .UpdateSpecification(Arg.Any <Specification>()) .Returns(HttpStatusCode.OK); ISearchRepository <SpecificationIndex> searchRepository = CreateSearchRepository(); searchRepository .Index(Arg.Any <IEnumerable <SpecificationIndex> >()) .Returns(new[] { new IndexError() { ErrorMessage = errorMessage } }); ICacheProvider cacheProvider = CreateCacheProvider(); IMessengerService messengerService = CreateMessengerService(); SpecificationVersion newSpecVersion = specification.Current.Clone() as SpecificationVersion; newSpecVersion.Name = specificationEditModel.Name; newSpecVersion.FundingPeriod.Id = specificationEditModel.FundingPeriodId; newSpecVersion.FundingStreams = new[] { new FundingStream { Id = "fs11" } }; IVersionRepository <SpecificationVersion> versionRepository = CreateVersionRepository(); versionRepository .CreateVersion(Arg.Any <SpecificationVersion>(), Arg.Any <SpecificationVersion>()) .Returns(newSpecVersion); SpecificationsService service = CreateService( logs: logger, specificationsRepository: specificationsRepository, searchRepository: searchRepository, cacheProvider: cacheProvider, messengerService: messengerService, specificationVersionRepository: versionRepository); //Act Func <Task <IActionResult> > editSpecification = async() => await service.EditSpecification(request); //Assert editSpecification .Should() .Throw <ApplicationException>() .Which .Message .Should() .Be($"Could not index specification {specification.Current.Id} because: {errorMessage}"); }
public async Task SpecificationsService_GetFundingStreamsForSpecificationById_WhenSpecificationContainsNoFundingStreams_ThenErrorReturned() { // Arrange const string specificationId = "spec1"; ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); SpecificationsService specificationsService = CreateService(specificationsRepository: specificationsRepository); IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "specificationId", new StringValues(specificationId) } }); HttpRequest request = Substitute.For <HttpRequest>(); request .Query .Returns(queryStringValues); Specification specification = new Specification() { Id = specificationId, Name = "Test Specification", Current = new SpecificationVersion() { FundingStreams = new List <Reference>() { }, }, }; specificationsRepository .GetSpecificationById(Arg.Is(specificationId)) .Returns(specification); List <FundingStream> fundingStreams = new List <FundingStream>(); specificationsRepository .GetFundingStreams(Arg.Any <Expression <Func <FundingStream, bool> > >()) .Returns(fundingStreams); // Act IActionResult actionResult = await specificationsService.GetFundingStreamsForSpecificationById(request); // Assert actionResult .Should() .BeOfType <InternalServerErrorResult>() .Which .Value .Should() .Be("Specification contains no funding streams"); await specificationsRepository .Received(1) .GetSpecificationById(Arg.Is(specificationId)); await specificationsRepository .Received(0) .GetFundingStreams(Arg.Any <Expression <Func <FundingStream, bool> > >()); }
public async Task SpecificationsService_GetFundingStreamsForSpecificationById_WhenRequestingASpecificationWhenExists_ThenFundingStreamsReturned() { // Arrange const string specificationId = "spec1"; ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); SpecificationsService specificationsService = CreateService(specificationsRepository: specificationsRepository); IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "specificationId", new StringValues(specificationId) } }); HttpRequest request = Substitute.For <HttpRequest>(); request .Query .Returns(queryStringValues); Specification specification = new Specification() { Id = specificationId, Name = "Test Specification", Current = new SpecificationVersion() { FundingStreams = new List <Reference>() { new Reference("fs1", "Funding Stream 1"), new Reference("fs2", "Funding Stream Two"), }, }, }; specificationsRepository .GetSpecificationById(Arg.Is(specificationId)) .Returns(specification); List <FundingStream> fundingStreams = new List <FundingStream>() { new FundingStream() { Id = "fs1", Name = "Funding Stream 1", AllocationLines = new List <AllocationLine>(), }, new FundingStream() { Id = "fs2", Name = "Funding Stream Two", AllocationLines = new List <AllocationLine>(), } }; specificationsRepository .GetFundingStreams(Arg.Any <Expression <Func <FundingStream, bool> > >()) .Returns(fundingStreams); // Act IActionResult actionResult = await specificationsService.GetFundingStreamsForSpecificationById(request); // Assert List <FundingStream> expectedFundingStreams = new List <FundingStream>() { new FundingStream() { Id = "fs1", Name = "Funding Stream 1", AllocationLines = new List <AllocationLine>(), }, new FundingStream() { Id = "fs2", Name = "Funding Stream Two", AllocationLines = new List <AllocationLine>(), } }; actionResult .Should() .BeOfType <OkObjectResult>() .Which .Value .Should().BeEquivalentTo(expectedFundingStreams.AsEnumerable()); await specificationsRepository .Received(1) .GetSpecificationById(Arg.Is(specificationId)); await specificationsRepository .Received(1) .GetFundingStreams(Arg.Any <Expression <Func <FundingStream, bool> > >()); }
public void CreateCalculation_WhenSomethingGoesWrongDuringIndexing_ShouldThrowException() { //Arrange const string errorMessage = "Encountered 802 error code"; AllocationLine allocationLine = new AllocationLine { Id = "02a6eeaf-e1a0-476e-9cf9-8aa5d9129345", Name = "test alloctaion" }; List <FundingStream> fundingStreams = new List <FundingStream>(); FundingStream fundingStream = new FundingStream { AllocationLines = new List <AllocationLine> { allocationLine }, Id = FundingStreamId }; fundingStreams.Add(fundingStream); Policy policy = new Policy { Id = PolicyId, Name = PolicyName, }; Specification specification = CreateSpecification(); specification.Current.Policies = new[] { policy }; specification.Current.FundingStreams = new List <Reference>() { new Reference { Id = FundingStreamId } }; CalculationCreateModel model = new CalculationCreateModel { SpecificationId = SpecificationId, PolicyId = PolicyId, AllocationLineId = AllocationLineId }; string json = JsonConvert.SerializeObject(model); byte[] byteArray = Encoding.UTF8.GetBytes(json); MemoryStream stream = new MemoryStream(byteArray); ClaimsPrincipal principle = new ClaimsPrincipal(new[] { new ClaimsIdentity(new [] { new Claim(ClaimTypes.Sid, UserId), new Claim(ClaimTypes.Name, Username) }) }); HttpContext context = Substitute.For <HttpContext>(); context .User .Returns(principle); HttpRequest request = Substitute.For <HttpRequest>(); request .Body .Returns(stream); request .HttpContext .Returns(context); IHeaderDictionary headerDictionary = new HeaderDictionary(); headerDictionary .Add("sfa-correlationId", new StringValues(SfaCorrelationId)); request .Headers .Returns(headerDictionary); ILogger logger = CreateLogger(); ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetSpecificationById(Arg.Is(SpecificationId)) .Returns(specification); specificationsRepository .GetFundingStreams(Arg.Any <Expression <Func <FundingStream, bool> > >()) .Returns(fundingStreams); specificationsRepository .UpdateSpecification(Arg.Is(specification)) .Returns(HttpStatusCode.OK); Calculation calculation = new Calculation { AllocationLine = new Reference() }; IMapper mapper = CreateMapper(); mapper .Map <Calculation>(Arg.Any <CalculationCreateModel>()) .Returns(calculation); IMessengerService messengerService = CreateMessengerService(); ISearchRepository <SpecificationIndex> mockSearchRepository = CreateSearchRepository(); mockSearchRepository .Index(Arg.Any <IEnumerable <SpecificationIndex> >()) .Returns(new List <IndexError>() { new IndexError() { ErrorMessage = errorMessage } }); SpecificationVersion newSpecVersion = specification.Current.Clone() as SpecificationVersion; newSpecVersion.PublishStatus = PublishStatus.Updated; newSpecVersion.Version = 2; IVersionRepository <SpecificationVersion> mockVersionRepository = CreateVersionRepository(); mockVersionRepository .CreateVersion(Arg.Any <SpecificationVersion>(), Arg.Any <SpecificationVersion>()) .Returns(newSpecVersion); SpecificationsService service = CreateService(logs: logger, specificationsRepository: specificationsRepository, mapper: mapper, messengerService: messengerService, specificationVersionRepository: mockVersionRepository, searchRepository: mockSearchRepository); //Act Func <Task <IActionResult> > createCalculation = async() => await service.CreateCalculation(request); //Assert createCalculation .Should() .Throw <ApplicationException>() .Which .Message .Should() .Be($"Could not index specification {specification.Current.Id} because: {errorMessage}"); }
public async Task CreateCalculation_GivenValidModelForSubPolicyAndSubPolicyFoundAndUpdated_ReturnsOK() { //Arrange AllocationLine allocationLine = new AllocationLine { Id = "02a6eeaf-e1a0-476e-9cf9-8aa5d9129345", Name = "test alloctaion" }; List <FundingStream> fundingStreams = new List <FundingStream>(); FundingStream fundingStream = new FundingStream { AllocationLines = new List <AllocationLine> { allocationLine }, Id = FundingStreamId }; fundingStreams.Add(fundingStream); Policy policy = new Policy { Id = PolicyId, Name = PolicyName, }; Specification specification = CreateSpecification(); specification.Current.Policies = new[] { policy }; specification.Current.FundingStreams = new List <Reference>() { new Reference { Id = FundingStreamId } }; CalculationCreateModel model = new CalculationCreateModel { SpecificationId = SpecificationId, PolicyId = PolicyId, AllocationLineId = AllocationLineId }; string json = JsonConvert.SerializeObject(model); byte[] byteArray = Encoding.UTF8.GetBytes(json); MemoryStream stream = new MemoryStream(byteArray); ClaimsPrincipal principle = new ClaimsPrincipal(new[] { new ClaimsIdentity(new [] { new Claim(ClaimTypes.Sid, UserId), new Claim(ClaimTypes.Name, Username) }) }); HttpContext context = Substitute.For <HttpContext>(); context .User .Returns(principle); HttpRequest request = Substitute.For <HttpRequest>(); request .Body .Returns(stream); request .HttpContext .Returns(context); IHeaderDictionary headerDictionary = new HeaderDictionary(); headerDictionary .Add("sfa-correlationId", new StringValues(SfaCorrelationId)); request .Headers .Returns(headerDictionary); ILogger logger = CreateLogger(); ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetSpecificationById(Arg.Is(SpecificationId)) .Returns(specification); specificationsRepository .GetFundingStreams(Arg.Any <Expression <Func <FundingStream, bool> > >()) .Returns(fundingStreams); specificationsRepository .UpdateSpecification(Arg.Is(specification)) .Returns(HttpStatusCode.OK); Calculation calculation = new Calculation { AllocationLine = new Reference() }; IMapper mapper = CreateMapper(); mapper .Map <Calculation>(Arg.Any <CalculationCreateModel>()) .Returns(calculation); IMessengerService messengerService = CreateMessengerService(); SpecificationVersion newSpecVersion = specification.Current.Clone() as SpecificationVersion; newSpecVersion.PublishStatus = PublishStatus.Updated; newSpecVersion.Version = 2; IVersionRepository <SpecificationVersion> mockVersionRepository = CreateVersionRepository(); mockVersionRepository .CreateVersion(Arg.Any <SpecificationVersion>(), Arg.Any <SpecificationVersion>()) .Returns(newSpecVersion); SpecificationsService service = CreateService(logs: logger, specificationsRepository: specificationsRepository, mapper: mapper, messengerService: messengerService, specificationVersionRepository: mockVersionRepository); //Act IActionResult result = await service.CreateCalculation(request); //Assert result .Should() .BeOfType <OkObjectResult>(); await messengerService .Received(1) .SendToQueue(Arg.Is("calc-events-create-draft"), Arg.Is <Models.Calcs.Calculation>(m => m.CalculationSpecification.Id == calculation.Id && m.CalculationSpecification.Name == calculation.Name && m.Name == calculation.Name && !string.IsNullOrEmpty(m.Id) && m.AllocationLine.Id == allocationLine.Id && m.AllocationLine.Name == allocationLine.Name), Arg.Is <IDictionary <string, string> >(m => m["user-id"] == UserId && m["user-name"] == Username && m["sfa-correlationId"] == SfaCorrelationId)); }
public async Task CreateCalculation_GivenValidModelAndPolicyFoundButAddingCalcCausesBadRequest_ReturnsBadRequest() { //Arrange AllocationLine allocationLine = new AllocationLine { Id = "02a6eeaf-e1a0-476e-9cf9-8aa5d9129345", Name = "test alloctaion" }; List <FundingStream> fundingStreams = new List <FundingStream>(); FundingStream fundingStream = new FundingStream { AllocationLines = new List <AllocationLine> { allocationLine }, Id = FundingStreamId }; fundingStreams.Add(fundingStream); Policy policy = new Policy { Id = PolicyId, Name = PolicyName, }; Specification specification = new Specification { Current = new SpecificationVersion() { Policies = new[] { policy, }, FundingStreams = new List <Reference>() { new Reference { Id = FundingStreamId } }, }, }; CalculationCreateModel model = new CalculationCreateModel { SpecificationId = SpecificationId, PolicyId = PolicyId, AllocationLineId = AllocationLineId }; string json = JsonConvert.SerializeObject(model); byte[] byteArray = Encoding.UTF8.GetBytes(json); MemoryStream stream = new MemoryStream(byteArray); HttpRequest request = Substitute.For <HttpRequest>(); request .Body .Returns(stream); ILogger logger = CreateLogger(); ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetSpecificationById(Arg.Is(SpecificationId)) .Returns(specification); specificationsRepository .GetFundingStreams(Arg.Any <Expression <Func <FundingStream, bool> > >()) .Returns(fundingStreams); specificationsRepository .UpdateSpecification(Arg.Is(specification)) .Returns(HttpStatusCode.BadRequest); Calculation calculation = new Calculation { AllocationLine = new Reference() }; IMapper mapper = CreateMapper(); mapper .Map <Calculation>(Arg.Any <CalculationCreateModel>()) .Returns(calculation); SpecificationsService service = CreateService(logs: logger, specificationsRepository: specificationsRepository, mapper: mapper); //Act IActionResult result = await service.CreateCalculation(request); //Assert result .Should() .BeOfType <StatusCodeResult>(); StatusCodeResult statusCodeResult = (StatusCodeResult)result; statusCodeResult .StatusCode .Should() .Be(400); logger .Received(1) .Error($"Failed to update specification when creating a calc with status BadRequest"); }