public async Task <IActionResult> GetFundingPeriodById(HttpRequest request) { request.Query.TryGetValue("fundingPeriodId", out StringValues fundingPeriodIdParse); string fundingPeriodId = fundingPeriodIdParse.FirstOrDefault(); if (string.IsNullOrWhiteSpace(fundingPeriodId)) { _logger.Error("No funding period was provided to GetFundingPeriodById"); return(new BadRequestObjectResult("Null or empty funding period id provided")); } Period fundingPeriod = await _specificationsRepository.GetPeriodById(fundingPeriodId); if (fundingPeriod == null) { _logger.Error($"No funding period was returned for funding period id: {fundingPeriodId}"); return(new NotFoundResult()); } return(new OkObjectResult(fundingPeriod)); }
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_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_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_GivenSpecificationWasFoundAndFundingPeriodChangedAndfundinfgStreamsChangedButFailsToFindFundingStreams_ReturnsInternalServerErrorResult() { //Arrange SpecificationEditModel specificationEditModel = new SpecificationEditModel { FundingPeriodId = "fp10" }; Period fundingPeriod = new Period { Id = "fp10", Name = "fp 10" }; 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); SpecificationsService service = CreateService(logs: logger, specificationsRepository: specificationsRepository); //Act IActionResult result = await service.EditSpecification(request); //Arrange result .Should() .BeOfType <InternalServerErrorResult>() .Which .Value .Should() .Be("No funding streams were retrieved to add to the Specification"); }
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_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)); }