private void AndTheSpecificationSummaryIsRetrieved(SpecificationSummary specificationSummary)
 {
     _specificationSummary = specificationSummary;
     _specificationService
     .GetSpecificationSummaryById(Arg.Is(_specificationId))
     .Returns(_specificationSummary);
 }
        public void ReturnsErrorMessageWhenSpecificationHasNoScopedProviders()
        {
            // Arrange
            string specificationId = "specId01";
            SpecificationSummary specificationSummary = new SpecificationSummary {
                Id = specificationId, ApprovalStatus = PublishStatus.Approved
            };

            string errorMessage = "Specification failed refresh prerequisite check. Reason: no scoped providers";

            // Act
            Func <Task> invocation
                = () => WhenThePreRequisitesAreChecked(specificationSummary, Enumerable.Empty <PublishedProvider>(), Enumerable.Empty <Provider>());

            // Assert
            invocation
            .Should()
            .Throw <JobPrereqFailedException>()
            .Where(_ =>
                   _.Message == $"Specification with id: '{specificationSummary.Id} has prerequisites which aren't complete.");

            _logger
            .Received()
            .Error(errorMessage);
        }
 private IDictionary <string, PublishedProvider> WhenGenerateMissingProviders(IEnumerable <Provider> scopedProviders,
                                                                              SpecificationSummary specification,
                                                                              Reference fundingStream,
                                                                              IDictionary <string, PublishedProvider> publishedProviders)
 {
     return(_providerService.GenerateMissingPublishedProviders(scopedProviders, specification, fundingStream, publishedProviders));
 }
        public async Task <IActionResult> GetLatestPublishedProvidersForSpecificationId(string specificationId)
        {
            ValidationResult validationResults = _validator.Validate(specificationId);

            if (!validationResults.IsValid)
            {
                return(validationResults.AsBadRequest());
            }

            SpecificationSummary specificationSummary = await _specificationService.GetSpecificationSummaryById(specificationId);

            List <PublishedProviderVersion> results = new List <PublishedProviderVersion>();

            foreach (var fundingStream in specificationSummary.FundingStreams)
            {
                IEnumerable <PublishedProvider> publishedProviders = await _resiliencePolicy.ExecuteAsync(() =>
                                                                                                          _publishedFunding.GetCurrentPublishedProviders(fundingStream.Id, specificationSummary.FundingPeriod.Id));

                if (publishedProviders.AnyWithNullCheck())
                {
                    results.AddRange(publishedProviders.Select(_ => _.Current));
                }
            }

            return(new OkObjectResult(results));
        }
Esempio n. 5
0
        public void CheckChooseForFundingStatus_GivenSpecificationSummaryNotFound_ThrowsEntityNotFoundException()
        {
            //Arrange
            SpecificationSummary specificationSummary = null;

            string errorMessage = $"Failed to find specification with for specification Id '{specificationId}'";

            ILogger logger = CreateLogger();

            ISpecificationService specificationService = CreateSpecificationService();

            specificationService
            .GetSpecificationSummaryById(Arg.Is(specificationId))
            .Returns(specificationSummary);

            SpecificationFundingStatusService specificationFundingStatusService = CreateSpecificationFundingStatusService(logger, specificationService);

            //Act
            Func <Task> test = async() => await specificationFundingStatusService.CheckChooseForFundingStatus(specificationId);

            //Assert
            test
            .Should()
            .ThrowExactly <EntityNotFoundException>()
            .Which
            .Message
            .Should()
            .Be(errorMessage);

            logger
            .Received(1)
            .Error(Arg.Is(errorMessage));
        }
        protected async override Task <IEnumerable <string> > PerformChecks <TSpecification>(TSpecification prereqObject, IEnumerable <PublishedProvider> publishedProviders = null, IEnumerable <Provider> providers = null)
        {
            Guard.ArgumentNotNull(publishedProviders, nameof(publishedProviders));

            SpecificationSummary specification = prereqObject as SpecificationSummary;

            Guard.ArgumentNotNull(specification, nameof(specification));

            SpecificationFundingStatus specificationFundingStatus = await _specificationFundingStatusService.CheckChooseForFundingStatus(specification);

            if (specificationFundingStatus != SpecificationFundingStatus.AlreadyChosen)
            {
                string errorMessage = $"Specification with id: '{specification.Id}' is not chosen for funding";

                _logger.Error(errorMessage);
                return(new string[] { errorMessage });
            }

            List <string> results = new List <string>();

            if (publishedProviders?.Any(_ => _.Current.Status == PublishedProviderStatus.Draft || _.Current.Status == PublishedProviderStatus.Updated) ?? false)
            {
                results.AddRange(publishedProviders.Where(_ => _.Current.Status == PublishedProviderStatus.Draft || _.Current.Status == PublishedProviderStatus.Updated).Select(_ => $"Provider with id:{_.Id} has current status:{_.Current.Status} so cannot be published."));
                _logger.Error(string.Join(Environment.NewLine, results));
                return(results);
            }

            return(results);
        }
        public void ReturnsErrorMessageWhenJobsRunning()
        {
            // Arrange
            string specificationId = "specId01";
            SpecificationSummary specificationSummary = new SpecificationSummary {
                Id = specificationId
            };

            string errorMessage = $"{JobConstants.DefinitionNames.CreateInstructAllocationJob} is still running";

            GivenTheSpecificationFundingStatusForTheSpecification(specificationSummary, SpecificationFundingStatus.AlreadyChosen);
            GivenCalculationEngineRunningStatusForTheSpecification(specificationId, JobConstants.DefinitionNames.CreateInstructAllocationJob);
            GivenValidationErrorsForTheSpecification(specificationSummary, Enumerable.Empty <string>());

            // Act
            Func <Task> invocation
                = () => WhenThePreRequisitesAreChecked(specificationSummary, Enumerable.Empty <PublishedProvider>(), Enumerable.Empty <Provider>());

            // Assert
            invocation
            .Should()
            .Throw <JobPrereqFailedException>()
            .Where(_ =>
                   _.Message == $"Specification with id: '{specificationSummary.Id} has prerequisites which aren't complete.");

            _logger
            .Received()
            .Error(errorMessage);
        }
Esempio n. 8
0
        public async Task <(long saveToCosmosElapsedMs, long saveToSearchElapsedMs)> SaveProviderResults(IEnumerable <ProviderResult> providerResults, int degreeOfParallelism = 5)
        {
            if (providerResults == null || providerResults.Count() == 0)
            {
                return(0, 0);
            }

            IEnumerable <KeyValuePair <string, ProviderResult> > results = providerResults.Select(m => new KeyValuePair <string, ProviderResult>(m.Provider.Id, m));

            IEnumerable <string> specificationIds = providerResults.Select(s => s.SpecificationId).Distinct();

            Dictionary <string, SpecificationSummary> specifications = new Dictionary <string, SpecificationSummary>();

            foreach (string specificationId in specificationIds)
            {
                SpecificationSummary specification = await _specificationsRepository.GetSpecificationSummaryById(specificationId);

                if (specification == null)
                {
                    throw new InvalidOperationException($"Result for Specification Summary lookup was null with ID '{specificationId}'");
                }

                specifications.Add(specificationId, specification);
            }

            Task <long> cosmosSaveTask = BulkSaveProviderResults(results, degreeOfParallelism);
            Task <long> searchSaveTask = UpdateSearch(providerResults, specifications);

            await TaskHelper.WhenAllAndThrow(cosmosSaveTask, searchSaveTask);

            return(cosmosSaveTask.Result, searchSaveTask.Result);
        }
Esempio n. 9
0
        public async Task Assemble_GivenSpecificationWithTwoFundingStreamsButTemplateContentsNotFoundForOneFundingStream_ReturnsCollectionWithOneItem()
        {
            //Arrange
            TemplateMetadataContents templateMetadataContents = new TemplateMetadataContents();

            SpecificationSummary specificationSummary = CreateSpecificationSummary();

            IPoliciesApiClient policiesApiClient = CreatePoliciesClient();

            policiesApiClient
            .GetFundingTemplateContents(Arg.Is("fs-1"), Arg.Is("fp-1"), Arg.Is("1.0"))
            .Returns(new ApiResponse <TemplateMetadataContents>(HttpStatusCode.OK, templateMetadataContents));
            policiesApiClient
            .GetFundingTemplateContents(Arg.Is("fs-2"), Arg.Is("fp-1"), Arg.Is("1.0"))
            .Returns((ApiResponse <TemplateMetadataContents>)null);

            TemplateMetadataContentsAssemblerService templateMetadataContentsAssemblerService = CreateService(policiesApiClient: policiesApiClient);

            //Act
            var templateMetadataContentsCollection = await templateMetadataContentsAssemblerService.Assemble(specificationSummary);

            //Assert
            templateMetadataContentsCollection
            .Should()
            .HaveCount(1);

            templateMetadataContentsCollection
            .First().Value
            .Should()
            .Be(templateMetadataContents);
        }
Esempio n. 10
0
        public async Task Assemble_GivenSpecificationWithTwoFundingStreamsAndTemplatesFound_ReturnsCollectionWithTwoItems()
        {
            //Arrange
            TemplateMetadataContents templateMetadataContentsFs1 = new TemplateMetadataContents();
            TemplateMetadataContents templateMetadataContentsFs2 = new TemplateMetadataContents();

            SpecificationSummary specificationSummary = CreateSpecificationSummary();

            IPoliciesApiClient policiesApiClient = CreatePoliciesClient();

            policiesApiClient
            .GetFundingTemplateContents(Arg.Is("fs-1"), Arg.Is("fp-1"), Arg.Is("1.0"))
            .Returns(new ApiResponse <TemplateMetadataContents>(HttpStatusCode.OK, templateMetadataContentsFs1));
            policiesApiClient
            .GetFundingTemplateContents(Arg.Is("fs-2"), Arg.Is("fp-1"), Arg.Is("1.0"))
            .Returns(new ApiResponse <TemplateMetadataContents>(HttpStatusCode.OK, templateMetadataContentsFs2));

            TemplateMetadataContentsAssemblerService templateMetadataContentsAssemblerService = CreateService(policiesApiClient: policiesApiClient);

            //Act
            var templateMetadataContentsCollection = await templateMetadataContentsAssemblerService.Assemble(specificationSummary);

            //Assert
            templateMetadataContentsCollection
            .Should()
            .HaveCount(2);
        }
        private async Task <(bool Complete, IEnumerable <MergeSpecificationRequest> items)> ProduceSpecificationInformation(CancellationToken cancellationToken,
                                                                                                                            dynamic context)
        {
            ICosmosDbFeedIterator <ProviderResult> feed = ((MergeContext)context).Feed;

            while (feed.HasMoreResults)
            {
                ProviderResult[] providerResults = (await feed.ReadNext(cancellationToken)).ToArray();

                Console.WriteLine($"Processing next {providerResults.Length} provider results");

                MergeSpecificationRequest[] requests = providerResults.Select(_ =>
                {
                    SpecificationSummary specificationSummary = GetSpecificationSummary(_.SpecificationId);

                    Console.WriteLine($"Creating merge specification request for provider {_.Provider.Id} and specification {_.SpecificationId}");

                    return(new MergeSpecificationRequest(new SpecificationInformation
                    {
                        Id = specificationSummary.Id,
                        Name = specificationSummary.Name,
                        FundingPeriodId = specificationSummary.FundingPeriod.Id,
                        LastEditDate = specificationSummary.LastEditedDate
                    },
                                                         _.Provider.Id));
                }).ToArray();

                return(false, requests);
            }

            return(true, ArraySegment <MergeSpecificationRequest> .Empty);
        }
        public async Task <IEnumerable <PublishedProvider> > GetPublishedProvidersForApproval(string specificationId, string[] publishedProviderIds = null)
        {
            Guard.IsNullOrWhiteSpace(specificationId, nameof(specificationId));

            SpecificationSummary specificationSummary = await _specificationsRepositoryPolicy.ExecuteAsync(
                () => _specificationService.GetSpecificationSummaryById(specificationId));

            ConcurrentBag <PublishedProvider> results = new ConcurrentBag <PublishedProvider>();

            string fundingPeriodId = specificationSummary?.FundingPeriod?.Id;

            if (fundingPeriodId.IsNullOrWhitespace())
            {
                string error = "Could not locate a funding period from the supplied funding period id on the specification summary";
                throw new InvalidOperationException(error);
            }

            List <KeyValuePair <string, string> > allPublishedProviderIds = new List <KeyValuePair <string, string> >();

            foreach (Common.Models.Reference fundingStream in specificationSummary.FundingStreams)
            {
                IEnumerable <KeyValuePair <string, string> > publishedProviders = await _publishedFundingRepositoryPolicy.ExecuteAsync(
                    () => _publishedFundingRepository.GetPublishedProviderIdsForApproval(fundingStream.Id, fundingPeriodId, publishedProviderIds));

                allPublishedProviderIds.AddRange(publishedProviders);
            }

            return(await _publishedFundingBulkRepository.GetPublishedProviders(allPublishedProviderIds));
        }
        public async Task <IEnumerable <string> > VerifyCalculationPrerequisites(SpecificationSummary specification)
        {
            List <string> validationErrors = new List <string>();

            string specificationId = specification.Id;

            ApiResponse <IEnumerable <CalculationMetadata> > calculationsResponse = await _policy.ExecuteAsync(() => _calcsApiClient.GetCalculationMetadataForSpecification(specificationId));

            if (calculationsResponse?.Content == null)
            {
                string errorMessage = $"Did locate any calculation metadata for specification {specificationId}. Unable to complete prerequisite checks";

                _logger.Error(errorMessage);
                validationErrors.Add(errorMessage);

                return(validationErrors);
            }

            validationErrors.AddRange(calculationsResponse?.Content.Where(_ => _.PublishStatus != PublishStatus.Approved && _.CalculationType == CalculationType.Template)
                                      .Select(_ => $"Calculation {_.Name} must be approved but is {_.PublishStatus}"));

            foreach (var fundingStream in specification.FundingStreams)
            {
                ApiResponse <TemplateMapping> templateMappingResponse = await _calcsApiClient.GetTemplateMapping(specificationId, fundingStream.Id);

                foreach (TemplateMappingItem calcInError in templateMappingResponse.Content.TemplateMappingItems.Where(c => string.IsNullOrWhiteSpace(c.CalculationId)))
                {
                    validationErrors.Add($"{calcInError.EntityType} {calcInError.Name} is not mapped to a calculation in CFS");
                }
            }

            return(validationErrors);
        }
        public void ReturnsErrorMessageWhenCanChooseSpecificationFundingAndErrorSelectingSpecificationForFunding()
        {
            // Arrange
            string specificationId = "specId01";
            SpecificationSummary specificationSummary = new SpecificationSummary {
                Id = specificationId, ApprovalStatus = PublishStatus.Approved
            };
            IEnumerable <Provider> providers = new[] { new Provider {
                                                           ProviderId = "ProviderId"
                                                       } };

            string errorMessage = "Generic error message";

            GivenTheSpecificationFundingStatusForTheSpecification(specificationSummary, SpecificationFundingStatus.CanChoose);
            GivenExceptionThrownForSelectSpecificationForFunding(specificationId, new Exception(errorMessage));

            // Act
            Func <Task> invocation
                = () => WhenThePreRequisitesAreChecked(specificationSummary, Enumerable.Empty <PublishedProvider>(), providers);

            // Assert
            invocation
            .Should()
            .Throw <JobPrereqFailedException>()
            .Where(_ =>
                   _.Message == $"Specification with id: '{specificationSummary.Id} has prerequisites which aren't complete.");

            _logger
            .Received()
            .Error(errorMessage);
        }
Esempio n. 15
0
        public async Task <IActionResult> OnGetAsync(string specificationId)
        {
            Guard.IsNullOrWhiteSpace(specificationId, nameof(specificationId));

            SpecificationId = specificationId;

            SpecificationSummary specification = await GetSpecification(specificationId);

            IsAuthorizedToEdit =
                await _authorizationHelper.DoesUserHavePermission(User, specification,
                                                                  SpecificationActionTypes.CanEditSpecification);

            if (specification != null)
            {
                SpecificationName = specification.Name;

                FundingPeriodName = specification.FundingPeriod.Name;

                FundingPeriodId = specification.FundingPeriod.Id;

                return(Page());
            }
            else
            {
                throw new InvalidOperationException($"Unable to retreive specification");
            }
        }
Esempio n. 16
0
        public async Task CheckChooseForFundingStatus_GivenNoSpecSummariesFoundForFundingPeriodId_ReturnsCanChoose()
        {
            //Arrange
            SpecificationSummary specificationSummary = new SpecificationSummary
            {
                FundingPeriod = new Reference
                {
                    Id = fundingPeriodId
                }
            };

            ISpecificationService specificationService = CreateSpecificationService();

            specificationService
            .GetSpecificationSummaryById(Arg.Is(specificationId))
            .Returns(specificationSummary);

            specificationService
            .GetSpecificationsSelectedForFundingByPeriod(Arg.Is(fundingPeriodId))
            .Returns((IEnumerable <SpecificationSummary>)null);

            SpecificationFundingStatusService specificationFundingStatusService = CreateSpecificationFundingStatusService(specificationService: specificationService);

            //Act
            SpecificationFundingStatus status = await specificationFundingStatusService.CheckChooseForFundingStatus(specificationId);

            //Assert
            status
            .Should()
            .Be(SpecificationFundingStatus.CanChoose);
        }
Esempio n. 17
0
        public async Task RunTests_GivenNoTestScenarios_LogsAndreturnsEmptyResults()
        {
            //Arrange
            IEnumerable <ProviderResult>        providerResults        = new[] { new ProviderResult() };
            IEnumerable <TestScenario>          scenarios              = new TestScenario[0];
            IEnumerable <ProviderSourceDataset> providerSourceDatasets = new ProviderSourceDataset[0];
            IEnumerable <TestScenarioResult>    testScenarioResults    = new TestScenarioResult[0];
            SpecificationSummary specificationSummary = new SpecificationSummary();
            BuildProject         buildProject         = new BuildProject();

            ILogger logger = CreateLogger();

            TestEngine testEngine = CreateTestEngine(logger: logger);

            //Act
            IEnumerable <TestScenarioResult> results = await testEngine.RunTests(scenarios, providerResults, providerSourceDatasets,
                                                                                 testScenarioResults, specificationSummary, buildProject);

            results
            .Count()
            .Should()
            .Be(0);

            logger
            .Received(1)
            .Warning(Arg.Is("No test scenarios were supplied to execute tests"));
        }
Esempio n. 18
0
        public async Task RunTests_GivenNoTestResults_LogsAndreturnsEmptyResults()
        {
            //Arrange
            IEnumerable <ProviderResult> providerResults = new[] { new ProviderResult {
                                                                       Provider = new ProviderSummary {
                                                                           Id = ProviderId
                                                                       }, SpecificationId = SpecificationId
                                                                   } };
            IEnumerable <TestScenario>          scenarios = new[] { new TestScenario() };
            IEnumerable <ProviderSourceDataset> providerSourceDatasets = new ProviderSourceDataset[0];
            IEnumerable <TestScenarioResult>    testScenarioResults    = new TestScenarioResult[0];
            SpecificationSummary specificationSummary = new SpecificationSummary();
            BuildProject         buildProject         = new BuildProject();

            ILogger logger = CreateLogger();

            TestEngine testEngine = CreateTestEngine(logger: logger);

            //Act
            IEnumerable <TestScenarioResult> results = await testEngine.RunTests(scenarios, providerResults, providerSourceDatasets,
                                                                                 testScenarioResults, specificationSummary, buildProject);

            results
            .Count()
            .Should()
            .Be(0);

            logger
            .Received(1)
            .Warning(Arg.Is($"No test results generated for provider: {ProviderId} on specification: {SpecificationId}"));
        }
        private async Task <UniqueTemplateContents> GetTemplateData(SpecificationSummary specification, string fundingStreamId)
        {
            UniqueTemplateContents uniqueTemplateContents = new UniqueTemplateContents();

            TemplateMetadataContents templateMetadata = await GetTemplateMetadataContents(specification, fundingStreamId);

            if (templateMetadata == null)
            {
                throw new NonRetriableException(
                          $"Did not locate template information for specification {specification.Id} in {fundingStreamId}. Unable to complete Qa Schema Generation");
            }

            IEnumerable <FundingLine> flattenedFundingLines = templateMetadata.RootFundingLines.Flatten(_ => _.FundingLines)
                                                              ?? new FundingLine[0];

            IEnumerable <FundingLine> uniqueFundingLines = flattenedFundingLines.GroupBy(x => x.TemplateLineId)
                                                           .Select(f => f.First());

            IEnumerable <Calculation> flattenedCalculations =
                flattenedFundingLines.SelectMany(_ => _.Calculations.Flatten(cal => cal.Calculations)) ?? new Calculation[0];

            IEnumerable <Calculation> uniqueFlattenedCalculations =
                flattenedCalculations.GroupBy(x => x.TemplateCalculationId)
                .Select(x => x.FirstOrDefault());

            uniqueTemplateContents.FundingLines = uniqueFundingLines;
            uniqueTemplateContents.Calculations = uniqueFlattenedCalculations;

            return(uniqueTemplateContents);
        }
        public async Task GetFundingConfigurations_GivenSuccessResponse_ReturnsDictionary()
        {
            //Arrange
            SpecificationSummary specificationSummary = CreateSpecificationSummary();

            IPoliciesApiClient policiesApiClient = CreatePoliciesApiClient();

            policiesApiClient
            .GetFundingConfiguration(Arg.Any <string>(), Arg.Any <string>())
            .Returns(new ApiResponse <FundingConfiguration>(System.Net.HttpStatusCode.OK, new FundingConfiguration()));

            FundingConfigurationService fundingConfigurationService = CreateService(policiesApiClient);

            //Act
            IDictionary <string, FundingConfiguration> results = await fundingConfigurationService.GetFundingConfigurations(specificationSummary);

            //Assert
            results
            .Should()
            .HaveCount(3);

            results["fs-1"]
            .Should()
            .NotBeNull();

            results["fs-2"]
            .Should()
            .NotBeNull();

            results["fs-3"]
            .Should()
            .NotBeNull();
        }
Esempio n. 21
0
        public async Task <IDictionary <string, TemplateMetadataContents> > Assemble(SpecificationSummary specification)
        {
            Guard.ArgumentNotNull(specification, nameof(specification));

            IDictionary <string, TemplateMetadataContents> templateMetadataContentsCollection = new Dictionary <string, TemplateMetadataContents>();

            foreach (Reference fundingStreamReference in specification.FundingStreams)
            {
                string fundingStreamId = fundingStreamReference.Id;

                if (!specification.TemplateIds.ContainsKey(fundingStreamId))
                {
                    string errorMessage = $"Template version for funding stream id '{fundingStreamId}' not found for specification with id '{specification.Id}'";

                    _logger.Error(errorMessage);
                }
                else
                {
                    string templateVersion = specification.TemplateIds[fundingStreamId];

                    ApiResponse <TemplateMetadataContents> templateMetadataContentsResponse = await _policiesApiClient.GetFundingTemplateContents(fundingStreamId, specification.FundingPeriod.Id, templateVersion);

                    //AB: We will need to revisit this and throw an exception here but while the data is a bit naf
                    //just want to make sure we can load the page while testing

                    if (templateMetadataContentsResponse != null && templateMetadataContentsResponse.StatusCode.IsSuccess())
                    {
                        templateMetadataContentsCollection.Add(fundingStreamId, templateMetadataContentsResponse.Content);
                    }
                }
            }

            return(templateMetadataContentsCollection);
        }
        public async Task GetFundingStructure_GivenNoTemplateVersionForFundingStream_ReturnsServerError()
        {
            string publishedProviderVersionId = NewRandomString();
            string specificationId            = NewRandomString();
            string fundingPeriodId            = NewRandomString();
            string providerId      = NewRandomString();
            string fundingStreamId = NewRandomString();
            int    templateVersion = NewRandomNumber();

            PublishedProviderVersion publishedProviderVersion = NewPublishedProviderVersion(_ => _
                                                                                            .WithFundingStreamId(fundingStreamId)
                                                                                            .WithFundingPeriodId(fundingPeriodId)
                                                                                            .WithProviderId(providerId)
                                                                                            .WithSpecificationId(specificationId));

            SpecificationSummary specificationSummary = NewSpecificationSummary(_ => _.WithId(specificationId));

            _publishedFundingRepository.GetPublishedProviderVersionById(publishedProviderVersionId)
            .Returns(publishedProviderVersion);
            _specificationService.GetSpecificationSummaryById(specificationId)
            .Returns(specificationSummary);

            var result = await _service.GetPublishedProviderFundingStructure(publishedProviderVersionId);

            InternalServerErrorResult notFoundObjectResult = result.Should()
                                                             .BeAssignableTo <InternalServerErrorResult>()
                                                             .Which
                                                             .As <InternalServerErrorResult>();

            notFoundObjectResult.Value
            .Should()
            .Be($"Specification contains no matching template version for funding stream '{fundingStreamId}'");
        }
        public void ReturnsErrorMessageWhenCalculationPrequisitesNotMet()
        {
            // Arrange
            string specificationId = "specId01";
            SpecificationSummary specificationSummary = new SpecificationSummary {
                Id = specificationId, ApprovalStatus = PublishStatus.Approved
            };
            IEnumerable <Provider> providers = new[] { new Provider {
                                                           ProviderId = "ProviderId"
                                                       } };

            string errorMessage = "Error message";

            GivenTheSpecificationFundingStatusForTheSpecification(specificationSummary, SpecificationFundingStatus.AlreadyChosen);
            GivenCalculationEngineRunningStatusForTheSpecification(specificationId);
            GivenValidationErrorsForTheSpecification(specificationSummary, new List <string> {
                errorMessage
            });

            // Act
            Func <Task> invocation
                = () => WhenThePreRequisitesAreChecked(specificationSummary, Enumerable.Empty <PublishedProvider>(), providers);

            // Assert
            invocation
            .Should()
            .Throw <JobPrereqFailedException>()
            .Where(_ =>
                   _.Message == $"Specification with id: '{specificationSummary.Id} has prerequisites which aren't complete.");

            _logger
            .Received()
            .Error(errorMessage);
        }
 protected void GivenTheApiResponseDetailsForTheSuppliedId(SpecificationSummary specificationSummary,
                                                           HttpStatusCode statusCode = HttpStatusCode.OK)
 {
     Specifications.GetSpecificationSummaryById(SpecificationId)
     .Returns(new ApiResponse <SpecificationSummary>(statusCode,
                                                     specificationSummary));
 }
Esempio n. 25
0
        public async Task <SpecificationFundingStatus> CheckChooseForFundingStatus(SpecificationSummary specificationSummary)
        {
            Guard.ArgumentNotNull(specificationSummary, nameof(specificationSummary));

            if (specificationSummary.IsSelectedForFunding)
            {
                return(SpecificationFundingStatus.AlreadyChosen);
            }

            string fundingPeriodConfigId = specificationSummary.FundingPeriod.Id;

            IEnumerable <SpecificationSummary> specificationSummaries = await _specificationService.GetSpecificationsSelectedForFundingByPeriod(fundingPeriodConfigId);

            if (specificationSummaries.IsNullOrEmpty())
            {
                return(SpecificationFundingStatus.CanChoose);
            }

            HashSet <string> chosenFundingStreams = new HashSet <string>(specificationSummaries.SelectMany(m => m.FundingStreams.Select(fs => fs.Id)));

            IEnumerable <string> fundingStreamIds = specificationSummary.FundingStreams.Select(m => m.Id);

            if (chosenFundingStreams.Intersect(fundingStreamIds).Any())
            {
                return(SpecificationFundingStatus.SharesAlreadyChosenFundingStream);
            }
            else
            {
                return(SpecificationFundingStatus.CanChoose);
            }
        }
        public async Task GivenTheFollowingSpecificationExists(Table table)
        {
            SpecificationSummary specificationSummary = table.CreateInstance <SpecificationSummary>();

            await _currentSpecificationContext.Repo.AddSpecification(specificationSummary);

            _currentSpecificationContext.SpecificationId = specificationSummary.Id;
        }
Esempio n. 27
0
        public async Task <PublishedFundingInput> GeneratePublishedFundingInput(IDictionary <string, PublishedProvider> publishedProvidersForFundingStream,
                                                                                IEnumerable <Provider> scopedProviders,
                                                                                Reference fundingStream,
                                                                                SpecificationSummary specification,
                                                                                IEnumerable <PublishedProvider> publishedProvidersInScope)
        {
            Guard.ArgumentNotNull(publishedProvidersForFundingStream, nameof(publishedProvidersForFundingStream));
            Guard.ArgumentNotNull(scopedProviders, nameof(scopedProviders));
            Guard.ArgumentNotNull(fundingStream, nameof(fundingStream));
            Guard.ArgumentNotNull(specification, nameof(specification));

            _logger.Information($"Fetching existing published funding");

            // Get latest version of existing published funding
            IEnumerable <PublishedFunding> publishedFunding = await _publishingResiliencePolicy.ExecuteAsync(() =>
                                                                                                             _publishedFundingDataService.GetCurrentPublishedFunding(fundingStream.Id, specification.FundingPeriod.Id));

            _logger.Information($"Fetched {publishedFunding.Count()} existing published funding items");

            _logger.Information($"Generating organisation groups");

            FundingConfiguration fundingConfiguration = await _policiesService.GetFundingConfiguration(fundingStream.Id, specification.FundingPeriod.Id);

            TemplateMetadataContents templateMetadataContents = await ReadTemplateMetadataContents(fundingStream, specification);

            // Foreach group, determine the provider versions required to be latest
            IEnumerable <OrganisationGroupResult> organisationGroups =
                await _organisationGroupGenerator.GenerateOrganisationGroup(fundingConfiguration, _mapper.Map <IEnumerable <ApiProvider> >(scopedProviders), specification.ProviderVersionId, specification.ProviderSnapshotId);

            // filter out organisation groups which don't contain a provider which is in scope
            if (!publishedProvidersInScope.IsNullOrEmpty())
            {
                HashSet <string> publishedProviderIdsInScope = new HashSet <string>(publishedProvidersInScope.DistinctBy(_ => _.Current.ProviderId).Select(_ => _.Current.ProviderId));
                organisationGroups = organisationGroups.Where(_ => _.Providers.Any(provider => publishedProviderIdsInScope.Contains(provider.ProviderId)));
            }

            _logger.Information($"A total of {organisationGroups.Count()} were generated");

            _logger.Information($"Generating organisation groups to save");

            // Compare existing published provider versions with existing current PublishedFundingVersion
            IEnumerable <(PublishedFunding PublishedFunding, OrganisationGroupResult OrganisationGroupResult)> organisationGroupsToSave =
                _publishedFundingChangeDetectorService.GenerateOrganisationGroupsToSave(organisationGroups, publishedFunding, publishedProvidersForFundingStream);

            _logger.Information($"A total of {organisationGroupsToSave.Count()} organisation groups returned to save");

            // Generate PublishedFundingVersion for new and updated PublishedFundings
            return(new PublishedFundingInput()
            {
                OrganisationGroupsToSave = organisationGroupsToSave,
                TemplateMetadataContents = templateMetadataContents,
                TemplateVersion = specification.TemplateIds[fundingStream.Id],
                FundingStream = fundingStream,
                FundingPeriod = await _policiesService.GetFundingPeriodByConfigurationId(specification.FundingPeriod.Id),
                PublishingDates = await _publishedFundingDateService.GetDatesForSpecification(specification.Id),
                SpecificationId = specification.Id,
            });
        }
        private bool HaveDifferentTemplateVersions(SpecificationSummary source, SpecificationSummary destination)
        {
            /*
             * Ensure the template versions of specifications are the same between source and destination
             */

            return(!(source.TemplateIds ?? Enumerable.Empty <KeyValuePair <string, string> >())
                   .SequenceEqual(destination.TemplateIds ?? Enumerable.Empty <KeyValuePair <string, string> >()));
        }
Esempio n. 29
0
 private void GivenSpecificationSummary(
     HttpStatusCode httpStatusCode,
     SpecificationSummary specificationSummary = null)
 {
     _specificationApiClient
     .Setup(_ => _.GetSpecificationSummaryById(
                _specificationId))
     .ReturnsAsync(new ApiResponse <SpecificationSummary>(httpStatusCode, specificationSummary));
 }
        public async Task <IActionResult> GetPreviousProfilesForSpecificationForProviderForFundingLine(
            string specificationId,
            string providerId,
            string fundingStreamId,
            string fundingLineCode)
        {
            Guard.ArgumentNotNull(fundingStreamId, nameof(fundingStreamId));
            Guard.ArgumentNotNull(specificationId, nameof(specificationId));
            Guard.ArgumentNotNull(providerId, nameof(providerId));
            Guard.ArgumentNotNull(fundingLineCode, nameof(fundingLineCode));

            ApiResponse <IEnumerable <FundingLineChange> > fundingLineApiResponse = await _publishingApiClient
                                                                                    .GetPreviousProfilesForSpecificationForProviderForFundingLine(
                specificationId,
                providerId,
                fundingStreamId,
                fundingLineCode);

            IActionResult fundingLineErrorResult =
                fundingLineApiResponse.IsSuccessOrReturnFailureResult(nameof(PublishedProviderVersion));

            if (fundingLineErrorResult != null)
            {
                return(fundingLineErrorResult);
            }

            ApiResponse <ProviderVersionSearchResult> providerResponse =
                await _providersApiClient.GetCurrentProviderForFundingStream(fundingStreamId, providerId);

            IActionResult providerErrorResult =
                providerResponse.IsSuccessOrReturnFailureResult(nameof(ProviderVersionSearchResult));

            if (providerErrorResult != null)
            {
                return(providerErrorResult);
            }

            ApiResponse <SpecificationSummary> specificationResponse = await _specificationsApiClient.GetSpecificationSummaryById(specificationId);

            IActionResult specificationErrorResult =
                specificationResponse.IsSuccessOrReturnFailureResult(nameof(SpecificationSummary));

            if (specificationErrorResult != null)
            {
                return(specificationErrorResult);
            }

            SpecificationSummary specification = specificationResponse.Content;

            return(Ok(new FundingLineChangesViewModel
            {
                ProviderName = providerResponse.Content.Name,
                SpecificationName = specification.Name,
                FundingPeriodName = specification.FundingPeriod.Name,
                FundingLineChanges = fundingLineApiResponse.Content
            }));
        }