public QaSchemaService(IPoliciesApiClient policies,
                               ISpecificationsApiClient specificationsApiClient,
                               ITemplateMetadataResolver templateMetadataResolver,
                               ISqlSchemaGenerator schemaGenerator,
                               IQaRepository qaRepository,
                               IProfilingApiClient profilingClient,
                               ISqlNameGenerator sqlNames,
                               IPublishingResiliencePolicies resiliencePolicies)
        {
            Guard.ArgumentNotNull(policies, nameof(policies));
            Guard.ArgumentNotNull(specificationsApiClient, nameof(specificationsApiClient));
            Guard.ArgumentNotNull(templateMetadataResolver, nameof(templateMetadataResolver));
            Guard.ArgumentNotNull(schemaGenerator, nameof(schemaGenerator));
            Guard.ArgumentNotNull(qaRepository, nameof(qaRepository));
            Guard.ArgumentNotNull(profilingClient, nameof(profilingClient));
            Guard.ArgumentNotNull(sqlNames, nameof(sqlNames));

            _policies                 = policies;
            _specifications           = specificationsApiClient;
            _templateMetadataResolver = templateMetadataResolver;
            _schemaGenerator          = schemaGenerator;
            _qaRepository             = qaRepository;
            _profilingClient          = profilingClient;
            _sqlNames                 = sqlNames;
            _specificationResilience  = resiliencePolicies.SpecificationsApiClient;
            _policiesResilience       = resiliencePolicies.PoliciesApiClient;

            //TODO; extract all of the different table builders so that this can more easily tested
            //at the moment it needs a god test with too much setup to make much sense to anyone
        }
        public FundingTemplateService(
            ILogger logger,
            IFundingTemplateRepository fundingTemplateRepository,
            IPolicyResiliencePolicies policyResiliencePolicies,
            IFundingTemplateValidationService fundingTemplateValidationService,
            ICacheProvider cacheProvider,
            ITemplateMetadataResolver templateMetadataResolver,
            ITemplateBuilderService templateBuilderService,
            IMapper mapper)
        {
            Guard.ArgumentNotNull(logger, nameof(logger));
            Guard.ArgumentNotNull(fundingTemplateRepository, nameof(fundingTemplateRepository));
            Guard.ArgumentNotNull(policyResiliencePolicies?.CacheProvider, nameof(policyResiliencePolicies.CacheProvider));
            Guard.ArgumentNotNull(policyResiliencePolicies?.FundingTemplateRepository, nameof(policyResiliencePolicies.FundingTemplateRepository));
            Guard.ArgumentNotNull(fundingTemplateValidationService, nameof(fundingTemplateValidationService));
            Guard.ArgumentNotNull(cacheProvider, nameof(cacheProvider));
            Guard.ArgumentNotNull(templateMetadataResolver, nameof(templateMetadataResolver));
            Guard.ArgumentNotNull(templateBuilderService, nameof(templateBuilderService));
            Guard.ArgumentNotNull(mapper, nameof(mapper));

            _logger = logger;
            _fundingTemplateRepository        = fundingTemplateRepository;
            _fundingTemplateRepositoryPolicy  = policyResiliencePolicies.FundingTemplateRepository;
            _fundingTemplateValidationService = fundingTemplateValidationService;
            _cacheProvider            = cacheProvider;
            _cacheProviderPolicy      = policyResiliencePolicies.CacheProvider;
            _templateMetadataResolver = templateMetadataResolver;
            _templateBuilderService   = templateBuilderService;
            _mapper = mapper;
        }
        private static FundingTemplateService CreateFundingTemplateService(
            ILogger logger = null,
            IFundingTemplateRepository fundingTemplateRepository = null,
            IFundingTemplateValidationService fundingTemplateValidationService = null,
            ICacheProvider cacheProvider = null,
            ITemplateMetadataResolver templateMetadataResolver = null,
            ITemplateBuilderService templateBuilderService     = null,
            IMapper mapper = null)
        {
            if (mapper == null)
            {
                MapperConfiguration fundingConfMappingConfig = new MapperConfiguration(c =>
                {
                    c.AddProfile <FundingConfigurationMappingProfile>();
                });

                mapper = fundingConfMappingConfig.CreateMapper();
            }

            return(new FundingTemplateService(
                       logger ?? CreateLogger(),
                       fundingTemplateRepository ?? CreateFundingTemplateRepository(),
                       PolicyResiliencePoliciesTestHelper.GenerateTestPolicies(),
                       fundingTemplateValidationService ?? CreateFundingTemplateValidationService(),
                       cacheProvider ?? CreateCacheProvider(),
                       templateMetadataResolver ?? CreateMetadataResolver(),
                       templateBuilderService ?? CreateTemplateBuilderService(),
                       mapper
                       ));
        }
        public async Task SaveFundingTemplate_GivenInvalidTemplateDueToProfilePeriods_BadRequest()
        {
            //Arrange
            string template        = CreateJsonFile("CalculateFunding.Services.Policy.Resources.LogicalModelTemplate.json");
            string fundingStreamId = "PES";
            string templateVersion = "1.5";
            string fundingPeriodId = "AY-2020";

            FundingTemplateValidationResult validationResult = new FundingTemplateValidationResult
            {
                TemplateVersion = templateVersion,
                FundingStreamId = fundingStreamId,
                SchemaVersion   = "1.0",
            };

            ITemplateMetadataResolver templateMetadataResolver = CreateMetadataResolver("1.0");

            IFundingTemplateValidationService fundingTemplateValidationService = CreateFundingTemplateValidationService();

            fundingTemplateValidationService
            .ValidateFundingTemplate(Arg.Is(template), Arg.Is(fundingStreamId), Arg.Is(fundingPeriodId), Arg.Is(templateVersion))
            .Returns(validationResult);

            IFundingTemplateRepository fundingTemplateRepository = CreateFundingTemplateRepository();

            ILogger logger = CreateLogger();

            ICacheProvider cacheProvider = CreateCacheProvider();

            FundingTemplateService fundingTemplateService = CreateFundingTemplateService(
                logger,
                fundingTemplateValidationService: fundingTemplateValidationService,
                fundingTemplateRepository: fundingTemplateRepository,
                cacheProvider: cacheProvider,
                templateMetadataResolver: templateMetadataResolver);

            //Act
            IActionResult result = await fundingTemplateService.SaveFundingTemplate(createdAtActionName, createdAtControllerName, template, fundingStreamId, fundingPeriodId, templateVersion);

            //Assert
            result
            .Should()
            .BeAssignableTo <BadRequestObjectResult>();

            BadRequestObjectResult badRequestObjectResult = result as BadRequestObjectResult;

            SerializableError validationResults = badRequestObjectResult.Value as SerializableError;

            validationResults
            .Count()
            .Should()
            .Be(1);

            ((string[])validationResults["DistributionPeriods"])[0]
            .Should()
            .Be("Funding line : 'Total funding line' has values for the distribution periods");
        }
예제 #5
0
        public SqlImportContextBuilder(ICosmosRepository cosmos,
                                       IPoliciesApiClient policies,
                                       ITemplateMetadataResolver templateMetadataResolver,
                                       ISpecificationsApiClient specifications,
                                       IPublishingResiliencePolicies resiliencePolicies)
        {
            Guard.ArgumentNotNull(cosmos, nameof(cosmos));
            Guard.ArgumentNotNull(policies, nameof(policies));
            Guard.ArgumentNotNull(templateMetadataResolver, nameof(templateMetadataResolver));
            Guard.ArgumentNotNull(specifications, nameof(specifications));
            Guard.ArgumentNotNull(resiliencePolicies?.SpecificationsApiClient, nameof(resiliencePolicies.SpecificationsApiClient));
            Guard.ArgumentNotNull(resiliencePolicies?.PoliciesApiClient, nameof(resiliencePolicies.PoliciesApiClient));

            _cosmos   = cosmos;
            _policies = policies;
            _templateMetadataResolver = templateMetadataResolver;
            _specifications           = specifications;
            _specificationResilience  = resiliencePolicies.SpecificationsApiClient;
            _policiesResilience       = resiliencePolicies.PoliciesApiClient;
        }
예제 #6
0
 public TemplateBuilderService(
     IIoCValidatorFactory validatorFactory,
     IFundingTemplateValidationService fundingTemplateValidationService,
     ITemplateMetadataResolver templateMetadataResolver,
     ITemplateVersionRepository templateVersionRepository,
     ITemplateRepository templateRepository,
     ISearchRepository <TemplateIndex> searchRepository,
     IPolicyRepository policyRepository,
     ITemplateBlobService templateBlobService,
     ILogger logger)
 {
     _validatorFactory = validatorFactory;
     _fundingTemplateValidationService = fundingTemplateValidationService;
     _templateMetadataResolver         = templateMetadataResolver;
     _templateVersionRepository        = templateVersionRepository;
     _templateRepository  = templateRepository;
     _searchRepository    = searchRepository;
     _policyRepository    = policyRepository;
     _templateBlobService = templateBlobService;
     _fundingTemplateValidationService = fundingTemplateValidationService;
     _logger = logger;
 }
            private void SetupMocks()
            {
                _validatorFactory = Substitute.For <IIoCValidatorFactory>();
                _validatorFactory.Validate(Arg.Any <object>()).Returns(new ValidationResult());
                _templateRepository   = Substitute.For <ITemplateRepository>();
                _templateVersionFirst = new TemplateVersion
                {
                    Name            = "XXX 20-21",
                    TemplateId      = _command.TemplateId,
                    TemplateJson    = null,
                    Version         = 1,
                    MinorVersion    = 1,
                    MajorVersion    = 0,
                    SchemaVersion   = "1.1",
                    FundingStreamId = "XX",
                    FundingPeriodId = "20-21",
                    Status          = TemplateStatus.Published,
                    Author          = new Reference("111", "FirstTestUser")
                };
                _templateBeforeUpdate = new Template
                {
                    Name          = "Template Name",
                    Description   = "Description",
                    TemplateId    = _command.TemplateId,
                    FundingPeriod = new FundingPeriod
                    {
                        Id   = "20-21",
                        Name = "Test Period",
                        Type = FundingPeriodType.FY
                    },
                    FundingStream = new FundingStream
                    {
                        Id        = "XX",
                        ShortName = "XX",
                        Name      = "FundingSteam"
                    },
                    Current = _templateVersionFirst
                };

                _templateMetadataGenerator = Substitute.For <ITemplateMetadataGenerator>();
                _templateMetadataGenerator.Validate(Arg.Any <string>()).Returns(new ValidationResult());
                _templateMetadataResolver = Substitute.For <ITemplateMetadataResolver>();
                _templateMetadataResolver.GetService(Arg.Any <string>()).Returns(_templateMetadataGenerator);
                _templateValidationService = Substitute.For <IFundingTemplateValidationService>();
                _templateValidationService.ValidateFundingTemplate(Arg.Any <string>(), Arg.Any <string>(), Arg.Any <string>(), null).Returns(new FundingTemplateValidationResult {
                });
                _templateRepository.GetTemplate(Arg.Is(_command.TemplateId)).Returns(_templateBeforeUpdate);
                _templateRepository.Update(Arg.Do <Template>(x => _savedTemplate = x)).Returns(HttpStatusCode.OK);

                _versionRepository = Substitute.For <ITemplateVersionRepository>();
                _versionRepository.SaveVersion(Arg.Do <TemplateVersion>(x => _savedTemplateVersion = x)).Returns(HttpStatusCode.OK);

                _searchRepository = Substitute.For <ISearchRepository <TemplateIndex> >();
                _searchRepository.Index(Arg.Any <IEnumerable <TemplateIndex> >()).Returns(Enumerable.Empty <IndexError>());

                _policyRepository = Substitute.For <IPolicyRepository>();
                _policyRepository.GetFundingPeriodById(Arg.Any <string>()).Returns(new FundingPeriod
                {
                    Id   = "2021",
                    Name = "Test Period",
                    Type = FundingPeriodType.FY
                });
                _policyRepository.GetFundingStreamById(Arg.Any <string>()).Returns(new FundingStream
                {
                    Id        = "XX",
                    ShortName = "XX",
                    Name      = "FundingSteam"
                });
                _templateBlobService = Substitute.For <ITemplateBlobService>();
                _templateBlobService.PublishTemplate(Arg.Any <Template>()).Returns(CommandResult.Success());
            }
            private void SetupMocks()
            {
                _validatorFactory = Substitute.For <IIoCValidatorFactory>();
                _validatorFactory.Validate(Arg.Any <object>()).Returns(new ValidationResult());
                _templateRepository    = Substitute.For <ITemplateRepository>();
                _sourceTemplateVersion = new TemplateVersion
                {
                    Name            = "Old Test Name",
                    TemplateId      = _command.CloneFromTemplateId,
                    TemplateJson    = "{ \"Lorem\": \"ipsum\" }",
                    Version         = 12,
                    FundingPeriodId = "19-20",
                    FundingStreamId = "OLD",
                    MinorVersion    = 1,
                    MajorVersion    = 0,
                    SchemaVersion   = "1.1",
                    Status          = TemplateStatus.Draft,
                    Author          = new Reference("111", "FirstTestUser")
                };
                _sourceTemplate = new Template
                {
                    Name          = _sourceTemplateVersion.Name,
                    Description   = "Old description",
                    TemplateId    = _command.CloneFromTemplateId,
                    FundingPeriod = new FundingPeriod
                    {
                        Id   = "2021",
                        Name = "Test Period",
                        Type = FundingPeriodType.FY
                    },
                    FundingStream = new FundingStream
                    {
                        Id        = "XX",
                        ShortName = "XX",
                        Name      = "FundingSteam"
                    },
                    Current = _sourceTemplateVersion
                };

                _templateMetadataGenerator = Substitute.For <ITemplateMetadataGenerator>();
                _templateMetadataGenerator.Validate(Arg.Any <string>()).Returns(new ValidationResult());
                _templateMetadataResolver = Substitute.For <ITemplateMetadataResolver>();
                _templateMetadataResolver.GetService(Arg.Any <string>()).Returns(_templateMetadataGenerator);
                _templateValidationService = Substitute.For <IFundingTemplateValidationService>();
                _templateValidationService.ValidateFundingTemplate(Arg.Any <string>(), Arg.Any <string>(), Arg.Any <string>(), null).Returns(new FundingTemplateValidationResult {
                });
                _templateRepository.GetTemplate(Arg.Is(_command.CloneFromTemplateId)).Returns(_sourceTemplate);
                _templateRepository.GetAllTemplates().Returns(new[] { _sourceTemplate });
                _templateRepository.CreateDraft(Arg.Any <Template>()).Returns(HttpStatusCode.OK);

                _versionRepository = Substitute.For <ITemplateVersionRepository>();
                _versionRepository.SaveVersion(Arg.Any <TemplateVersion>()).Returns(HttpStatusCode.OK);

                _policyRepository = Substitute.For <IPolicyRepository>();
                _policyRepository.GetFundingPeriods().Returns(new[] {
                    new FundingPeriod
                    {
                        Id   = "2021",
                        Name = "Test Period",
                        Type = FundingPeriodType.FY
                    },
                    new FundingPeriod
                    {
                        Id   = _command.FundingPeriodId,
                        Name = "Test Funding Period 2"
                    }
                });
                _policyRepository.GetFundingStreams().Returns(new[] {
                    new FundingStream
                    {
                        Id        = "XX",
                        ShortName = "XX",
                        Name      = "FundingSteam"
                    },
                    new FundingStream
                    {
                        Id        = _command.FundingStreamId,
                        Name      = "Funding Stream 2",
                        ShortName = "Stream 2"
                    }
                });
                _policyRepository.GetFundingConfigurations().Returns(new[] { new FundingConfiguration
                                                                             {
                                                                                 FundingStreamId = _command.FundingStreamId,
                                                                                 FundingPeriodId = _command.FundingPeriodId
                                                                             } });

                _templateIndexer = Substitute.For <ISearchRepository <TemplateIndex> >();

                _templateBlobService = Substitute.For <ITemplateBlobService>();
                _templateBlobService.PublishTemplate(Arg.Any <Template>()).Returns(CommandResult.Success());
            }
        public async Task SaveFundingTemplate_GivenValidTemplateAndSaves_InvalidatesCacheReturnsCreatedAtActionResult()
        {
            //Arrange
            string template        = CreateJsonFile("CalculateFunding.Services.Policy.Resources.LogicalModelTemplateNoProfilePeriods.json");
            string fundingStreamId = "PES";
            string templateVersion = "1.5";
            string fundingPeriodId = "AY-2020";

            FundingTemplateValidationResult validationResult = new FundingTemplateValidationResult
            {
                TemplateVersion = templateVersion,
                FundingStreamId = fundingStreamId,
                SchemaVersion   = "1.0",
                FundingPeriodId = fundingPeriodId
            };

            string cacheKey = $"{CacheKeys.FundingTemplatePrefix}{validationResult.FundingStreamId}-{validationResult.FundingPeriodId}-{validationResult.TemplateVersion}".ToLowerInvariant();

            ITemplateMetadataResolver templateMetadataResolver = CreateMetadataResolver("1.0");

            IFundingTemplateValidationService fundingTemplateValidationService = CreateFundingTemplateValidationService();

            fundingTemplateValidationService
            .ValidateFundingTemplate(Arg.Is(template), Arg.Is(fundingStreamId), Arg.Is(fundingPeriodId), Arg.Is(templateVersion))
            .Returns(validationResult);

            IFundingTemplateRepository fundingTemplateRepository = CreateFundingTemplateRepository();

            ILogger logger = CreateLogger();

            ICacheProvider cacheProvider = CreateCacheProvider();

            FundingTemplateService fundingTemplateService = CreateFundingTemplateService(
                logger,
                fundingTemplateValidationService: fundingTemplateValidationService,
                fundingTemplateRepository: fundingTemplateRepository,
                cacheProvider: cacheProvider,
                templateMetadataResolver: templateMetadataResolver);

            //Act
            IActionResult result = await fundingTemplateService.SaveFundingTemplate(createdAtActionName, createdAtControllerName, template, fundingStreamId, fundingPeriodId, templateVersion);

            //Assert
            result
            .Should()
            .BeAssignableTo <CreatedAtActionResult>();

            CreatedAtActionResult actionResult = result as CreatedAtActionResult;

            actionResult
            .ActionName
            .Should()
            .Be(createdAtActionName);

            actionResult
            .ControllerName
            .Should()
            .Be(createdAtControllerName);

            actionResult
            .RouteValues["fundingStreamId"].ToString()
            .Should()
            .Be("PES");

            actionResult
            .RouteValues["fundingPeriodId"].ToString()
            .Should()
            .Be("AY-2020");

            actionResult
            .RouteValues["templateVersion"].ToString()
            .Should()
            .Be("1.5");

            await
            cacheProvider
            .Received(1)
            .RemoveAsync <string>(Arg.Is(cacheKey));

            await
            cacheProvider
            .Received(1)
            .RemoveAsync <FundingTemplateContents>(Arg.Is($"{CacheKeys.FundingTemplateContents}pes:ay-2020:1.5"));

            await cacheProvider
            .Received(1)
            .RemoveAsync <TemplateMetadataContents>($"{CacheKeys.FundingTemplateContentMetadata}pes:ay-2020:1.5");

            await cacheProvider
            .Received(1)
            .RemoveAsync <TemplateMetadataDistinctContents>($"{CacheKeys.FundingTemplateContentMetadataDistinct}pes:ay-2020:1.5");
        }
        public async Task SaveFundingTemplate_GivenValidTemplateButFailedToSaveToBlobStorage_ReturnsInternalServerError()
        {
            //Arrange
            const string template        = "a template";
            string       fundingStreamId = NewRandomString();
            string       templateVersion = NewRandomString();
            string       fundingPeriodId = NewRandomString();

            FundingTemplateValidationResult validationResult = new FundingTemplateValidationResult
            {
                TemplateVersion = "1.8",
                FundingStreamId = "PES",
                SchemaVersion   = "1.0",
                FundingPeriodId = "AY-2020"
            };

            string blobName = $"{validationResult.FundingStreamId}/{validationResult.FundingPeriodId}/{validationResult.TemplateVersion}.json";

            IFundingTemplateValidationService fundingTemplateValidationService = CreateFundingTemplateValidationService();

            fundingTemplateValidationService
            .ValidateFundingTemplate(Arg.Is(template), Arg.Is(fundingStreamId), Arg.Is(fundingPeriodId), Arg.Is(templateVersion))
            .Returns(validationResult);

            IFundingTemplateRepository fundingTemplateRepository = CreateFundingTemplateRepository();

            fundingTemplateRepository
            .When(x => x.SaveFundingTemplateVersion(Arg.Is(blobName), Arg.Any <byte[]>()))
            .Do(x => { throw new Exception(); });

            ILogger logger = CreateLogger();

            ITemplateMetadataGenerator templateMetadataGenerator = CreateMetadataGenerator();

            templateMetadataGenerator.Validate(Arg.Is <string>(template))
            .Returns(new FluentValidation.Results.ValidationResult());

            ITemplateMetadataResolver templateMetadataResolver = CreateMetadataResolver("1.0", templateMetadataGenerator);

            FundingTemplateService fundingTemplateService = CreateFundingTemplateService(
                logger,
                fundingTemplateValidationService: fundingTemplateValidationService,
                fundingTemplateRepository: fundingTemplateRepository,
                templateMetadataResolver: templateMetadataResolver);

            //Act
            IActionResult result = await fundingTemplateService.SaveFundingTemplate(createdAtActionName, createdAtControllerName, template, fundingStreamId, fundingPeriodId, templateVersion);

            //Assert
            result
            .Should()
            .BeAssignableTo <InternalServerErrorResult>()
            .Which
            .Value
            .Should()
            .Be("Error occurred uploading funding template");

            logger
            .Received(1)
            .Error(Arg.Any <NonRetriableException>(), Arg.Is($"Failed to save funding template '{blobName}' to blob storage"));
        }