private static ISpecificationsRepository CreateSpecificationsRepository(bool hasSpecification = false) { ISpecificationsRepository repository = Substitute.For <ISpecificationsRepository>(); repository .GetSpecificationByQuery(Arg.Any <Expression <Func <DocumentEntity <Specification>, bool> > >()) .Returns(hasSpecification ? new Specification() : null); return(repository); }
public SpecificationEditModelValidator(ISpecificationsRepository specificationsRepository) { _specificationsRepository = specificationsRepository; RuleFor(model => model.Description) .NotEmpty() .WithMessage("You must give a description for the specification"); RuleFor(model => model.FundingPeriodId) .NotEmpty() .WithMessage("Null or empty academic year id provided"); RuleFor(model => model.FundingStreamIds) .NotNull() .NotEmpty() .WithMessage("You must select at least one funding stream") .Custom((name, context) => { SpecificationEditModel specModel = context.ParentContext.InstanceToValidate as SpecificationEditModel; foreach (string fundingStreamId in specModel.FundingStreamIds) { if (string.IsNullOrWhiteSpace(fundingStreamId)) { context.AddFailure($"A null or empty string funding stream ID was provided"); } } }); RuleFor(model => model.Name) .NotEmpty() .WithMessage("You must give a unique specification name") .Custom((name, context) => { SpecificationEditModel specModel = context.ParentContext.InstanceToValidate as SpecificationEditModel; if (string.IsNullOrWhiteSpace(specModel.SpecificationId)) { context.AddFailure("Specification ID not specified on the model"); return; } Specification specification = _specificationsRepository.GetSpecificationByQuery(m => m.Name.ToLower() == specModel.Name.ToLower() && m.Id != specModel.SpecificationId).Result; if (specification != null) { context.AddFailure($"You must give a unique specification name"); } }); }
public SpecificationCreateModelValidator(ISpecificationsRepository specificationsRepository, IProvidersApiClient providersApiClient, IPoliciesApiClient policiesApiClient, ISpecificationsResiliencePolicies resiliencePolicies) { Guard.ArgumentNotNull(specificationsRepository, nameof(specificationsRepository)); Guard.ArgumentNotNull(providersApiClient, nameof(providersApiClient)); Guard.ArgumentNotNull(policiesApiClient, nameof(policiesApiClient)); Guard.ArgumentNotNull(resiliencePolicies?.PoliciesApiClient, nameof(resiliencePolicies.PoliciesApiClient)); _specificationsRepository = specificationsRepository; _providersApiClient = providersApiClient; _policiesApiClient = policiesApiClient; _policiesApiClientPolicy = resiliencePolicies.PoliciesApiClient; RuleFor(model => model.FundingPeriodId) .NotEmpty() .WithMessage("Null or empty academic year id provided") .Custom((name, context) => { SpecificationCreateModel specModel = context.ParentContext.InstanceToValidate as SpecificationCreateModel; if (!string.IsNullOrWhiteSpace(specModel.FundingPeriodId)) { ApiResponse <PolicyModels.FundingPeriod> fundingPeriodResponse = _policiesApiClientPolicy.ExecuteAsync(() => _policiesApiClient.GetFundingPeriodById(specModel.FundingPeriodId)).GetAwaiter().GetResult(); if (fundingPeriodResponse?.StatusCode != HttpStatusCode.OK || fundingPeriodResponse?.Content == null) { context.AddFailure("Funding period not found"); } } }); RuleFor(model => model.ProviderVersionId) .Custom((name, context) => { SpecificationCreateModel specModel = context.ParentContext.InstanceToValidate as SpecificationCreateModel; ApiResponse <PolicyModels.FundingConfig.FundingConfiguration> fundingConfigResponse = _policiesApiClientPolicy.ExecuteAsync(() => _policiesApiClient.GetFundingConfiguration(specModel.FundingStreamIds.FirstOrDefault(), specModel.FundingPeriodId)).GetAwaiter().GetResult(); if (fundingConfigResponse?.StatusCode != HttpStatusCode.OK || fundingConfigResponse?.Content == null) { context.AddFailure("Funding config not found"); return; } switch (fundingConfigResponse.Content.ProviderSource) { case ProviderSource.CFS: { if (string.IsNullOrWhiteSpace(specModel.ProviderVersionId)) { context.AddFailure($"Null or empty provider version id"); } if (_providersApiClient.DoesProviderVersionExist(specModel.ProviderVersionId).Result == System.Net.HttpStatusCode.NotFound) { context.AddFailure($"Provider version id selected does not exist"); } if (specModel.CoreProviderVersionUpdates != CoreProviderVersionUpdates.Manual) { context.AddFailure($"CoreProviderVersionUpdates - {specModel.CoreProviderVersionUpdates} is not valid for provider source - {fundingConfigResponse.Content.ProviderSource}"); } break; } case ProviderSource.FDZ: { if (!specModel.ProviderSnapshotId.HasValue) { context.AddFailure($"Null or empty provider snapshot id"); } break; } } }); RuleFor(model => model.FundingStreamIds) .NotNull() .NotEmpty() .WithMessage("You must select at least one funding stream") .Custom((name, context) => { SpecificationCreateModel specModel = context.ParentContext.InstanceToValidate as SpecificationCreateModel; foreach (string fundingStreamId in specModel.FundingStreamIds) { if (string.IsNullOrWhiteSpace(fundingStreamId)) { context.AddFailure($"A null or empty string funding stream ID was provided"); } } }); RuleFor(model => model.Name) .NotEmpty() .WithMessage("You must give a unique specification name") .Custom((name, context) => { SpecificationCreateModel specModel = context.ParentContext.InstanceToValidate as SpecificationCreateModel; Specification specification = _specificationsRepository.GetSpecificationByQuery(m => m.Content.Name.ToLower() == specModel.Name.Trim().ToLower()).Result; if (specification != null) { context.AddFailure($"You must give a unique specification name"); } }); }
public async Task SpecificationsService_CreateSpecification_WhenValidInputProvided_ThenSpecificationIsCreated() { // Arrange const string fundingStreamId = "fs1"; const string fundingPeriodId = "fp1"; ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); ISearchRepository <SpecificationIndex> searchRepository = CreateSearchRepository(); IMapper mapper = CreateImplementedMapper(); IVersionRepository <SpecificationVersion> versionRepository = CreateVersionRepository(); SpecificationsService specificationsService = CreateService( specificationsRepository: specificationsRepository, searchRepository: searchRepository, mapper: mapper, specificationVersionRepository: versionRepository); SpecificationCreateModel specificationCreateModel = new SpecificationCreateModel() { Name = "Specification Name", Description = "Specification Description", FundingPeriodId = "fp1", FundingStreamIds = new List <string>() { fundingStreamId }, }; string json = JsonConvert.SerializeObject(specificationCreateModel); 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); specificationsRepository .GetSpecificationByQuery(Arg.Any <Expression <Func <Specification, bool> > >()) .Returns((Specification)null); Period fundingPeriod = new Period() { Id = fundingPeriodId, Name = "Funding Period 1" }; specificationsRepository .GetPeriodById(Arg.Is(fundingPeriodId)) .Returns(fundingPeriod); FundingStream fundingStream = new FundingStream() { Id = fundingStreamId, Name = "Funding Stream 1", AllocationLines = new List <AllocationLine>(), }; specificationsRepository .GetFundingStreamById(Arg.Is(fundingStreamId)) .Returns(fundingStream); DateTime createdDate = new DateTime(2018, 1, 2, 5, 6, 2); SpecificationVersion specificationVersion = new SpecificationVersion() { Description = "Specification Description", FundingPeriod = new Reference("fp1", "Funding Period 1"), Date = createdDate, PublishStatus = Models.Versioning.PublishStatus.Draft, FundingStreams = new List <Reference>() { new Reference(FundingStreamId, "Funding Stream 1") }, Name = "Specification Name", Version = 1, SpecificationId = SpecificationId }; versionRepository .CreateVersion(Arg.Any <SpecificationVersion>()) .Returns(specificationVersion); DocumentEntity <Specification> createdSpecification = new DocumentEntity <Specification>() { Content = new Specification() { Name = "Specification Name", Id = "createdSpec", Current = specificationVersion }, }; specificationsRepository .CreateSpecification(Arg.Is <Specification>( s => s.Name == specificationCreateModel.Name && s.Current.Description == specificationCreateModel.Description && s.Current.FundingPeriod.Id == fundingPeriodId)) .Returns(createdSpecification); // Act IActionResult result = await specificationsService.CreateSpecification(request); // Assert result .Should() .BeOfType <OkObjectResult>() .Which .Value .Should() .BeOfType <SpecificationCurrentVersion>() .And .NotBeNull(); await specificationsRepository .Received(1) .CreateSpecification(Arg.Is <Specification>( s => s.Name == specificationCreateModel.Name && s.Current.Description == specificationCreateModel.Description && s.Current.FundingPeriod.Id == fundingPeriodId)); await searchRepository .Received(1) .Index(Arg.Is <List <SpecificationIndex> >(c => c.Count() == 1 && !string.IsNullOrWhiteSpace(c.First().Id) && c.First().Name == specificationCreateModel.Name )); await versionRepository .Received(1) .SaveVersion(Arg.Is <SpecificationVersion>( m => !string.IsNullOrWhiteSpace(m.EntityId) && m.PublishStatus == Models.Versioning.PublishStatus.Draft && m.Description == "Specification Description" && m.FundingPeriod.Id == "fp1" && m.FundingPeriod.Name == "Funding Period 1" && m.FundingStreams.Any() && m.Name == "Specification Name" && m.Version == 1 )); }
public async Task SpecificationsService_CreateSpecification_WhenFundingStreamIDIsProvidedButDoesNotExist_ThenPreConditionFailedReturned() { // Arrange const string fundingStreamId = "fs1"; const string fundingStreamNotFoundId = "notfound"; const string fundingPeriodId = "fp1"; ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); ISearchRepository <SpecificationIndex> searchRepository = CreateSearchRepository(); IMapper mapper = CreateImplementedMapper(); SpecificationsService specificationsService = CreateService( specificationsRepository: specificationsRepository, searchRepository: searchRepository, mapper: mapper); SpecificationCreateModel specificationCreateModel = new SpecificationCreateModel() { Name = "Specification Name", Description = "Specification Description", FundingPeriodId = "fp1", FundingStreamIds = new List <string>() { fundingStreamId, fundingStreamNotFoundId, }, }; string json = JsonConvert.SerializeObject(specificationCreateModel); 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); specificationsRepository .GetSpecificationByQuery(Arg.Any <Expression <Func <Specification, bool> > >()) .Returns((Specification)null); Period fundingPeriod = new Period() { Id = fundingPeriodId, Name = "Funding Period 1" }; specificationsRepository .GetPeriodById(Arg.Is(fundingPeriodId)) .Returns(fundingPeriod); FundingStream fundingStream = new FundingStream() { Id = fundingStreamId, Name = "Funding Stream 1", AllocationLines = new List <AllocationLine>(), }; specificationsRepository .GetFundingStreamById(Arg.Is(fundingStreamId)) .Returns(fundingStream); specificationsRepository .GetFundingStreamById(Arg.Is(fundingStreamNotFoundId)) .Returns((FundingStream)null); // Act IActionResult result = await specificationsService.CreateSpecification(request); // Assert result .Should() .BeOfType <PreconditionFailedResult>() .Which .Value .Should() .Be("Unable to find funding stream with ID 'notfound'."); await specificationsRepository .Received(1) .GetFundingStreamById(Arg.Is(fundingStreamNotFoundId)); await specificationsRepository .Received(1) .GetFundingStreamById(Arg.Is(fundingStreamId)); }