public void Getters_WhenOnSubscriptionPage_ShouldReturnCorrectGeneratedValues() { // arrange SearchFeedV2 <string> searchFeedV2 = new SearchFeedV2 <string> { Top = 10, TotalCount = 45, PageRef = 5 }; // assert & act searchFeedV2 .Current .Should().BeNull(); searchFeedV2 .PreviousArchive .Should().Be(4); searchFeedV2 .NextArchive .Should().BeNull(); searchFeedV2 .Current .Should().BeNull(); searchFeedV2 .TotalPages .Should().Be(5); searchFeedV2 .IsArchivePage .Should().BeFalse(); }
public void Getters_WhenOnAMiddlePage_ShouldReturnCorrectGeneratedValues() { // arrange SearchFeedV2 <string> searchFeedV2 = new SearchFeedV2 <string> { Top = 10, TotalCount = 50, PageRef = 3 }; // assert & act searchFeedV2 .Current .Should().Be(3); searchFeedV2 .PreviousArchive .Should().Be(2); searchFeedV2 .NextArchive .Should().Be(4); searchFeedV2 .TotalPages .Should().Be(5); searchFeedV2 .IsArchivePage .Should().BeTrue(); }
public async Task <IActionResult> GetNotifications(HttpRequest request, int?pageRef, int?startYear = null, int?endYear = null, IEnumerable <string> fundingStreamIds = null, IEnumerable <string> allocationLineIds = null, IEnumerable <string> allocationStatuses = null, IEnumerable <string> ukprns = null, IEnumerable <string> laCodes = null, bool?isAllocationLineContractRequired = null, int?pageSize = MaxRecords) { pageSize = pageSize ?? MaxRecords; IEnumerable <string> statusesArray = allocationStatuses.IsNullOrEmpty() ? new[] { "Published" } : allocationStatuses; if (pageRef < 1) { return(new BadRequestObjectResult("Page ref should be at least 1")); } if (pageSize < 1 || pageSize > 500) { return(new BadRequestObjectResult($"Page size should be more that zero and less than or equal to {MaxRecords}")); } SearchFeedV2 <AllocationNotificationFeedIndex> searchFeed = await _feedsService.GetFeedsV2(pageRef, pageSize.Value, startYear, endYear, ukprns, laCodes, isAllocationLineContractRequired, statusesArray, fundingStreamIds, allocationLineIds); if (searchFeed == null || searchFeed.TotalCount == 0 || searchFeed.Entries.IsNullOrEmpty()) { return(new NotFoundResult()); } AtomFeed <AllocationModel> atomFeed = CreateAtomFeed(searchFeed, request); return(Formatter.ActionResult <AtomFeed <AllocationModel> >(request, atomFeed)); }
public async Task <SearchFeedV2 <AllocationNotificationFeedIndex> > GetFeedsV2(int?pageRef, int top, int?startYear = null, int?endYear = null, IEnumerable <string> ukprns = null, IEnumerable <string> laCodes = null, bool?isAllocationLineContractRequired = null, IEnumerable <string> statuses = null, IEnumerable <string> fundingStreamIds = null, IEnumerable <string> allocationLineIds = null) { if (pageRef < 1) { throw new ArgumentException("Page ref cannot be less than one", nameof(pageRef)); } if (top < 1) { top = 500; } FilterHelper filterHelper = new FilterHelper(); AddFiltersForNotification(startYear, endYear, ukprns, laCodes, isAllocationLineContractRequired, statuses, fundingStreamIds, allocationLineIds, filterHelper); if (pageRef == null) { SearchResults <AllocationNotificationFeedIndex> countSearchResults = await SearchResults(0, null, filterHelper.BuildAndFilterQuery()); SearchFeedV2 <AllocationNotificationFeedIndex> searchFeedCountResult = CreateSearchFeedResult(null, top, countSearchResults); pageRef = searchFeedCountResult.Last; } int skip = (pageRef.Value - 1) * top; string filters = filterHelper.Filters.IsNullOrEmpty() ? "" : filterHelper.BuildAndFilterQuery(); SearchResults <AllocationNotificationFeedIndex> searchResults = await SearchResults(top, skip, filters); return(CreateSearchFeedResult(pageRef, top, searchResults)); }
public async Task GetNotifications_GivenAcceptHeaderNotSupplied_ReturnsBadRequest() { //Arrange SearchFeedV2 <AllocationNotificationFeedIndex> feeds = new SearchFeedV2 <AllocationNotificationFeedIndex> { PageRef = 3, Top = 500, TotalCount = 3, Entries = CreateFeedIndexes() }; IAllocationNotificationsFeedsSearchService feedsSearchService = CreateSearchService(); feedsSearchService .GetFeedsV2(Arg.Is(3), Arg.Is(500)) .ReturnsForAnyArgs(feeds); AllocationNotificationFeedsService service = CreateService(feedsSearchService); HttpRequest request = Substitute.For <HttpRequest>(); request.Scheme.Returns("https"); request.Path.Returns(new PathString("/api/v1/test/3")); request.Host.Returns(new HostString("wherever.naf:12345")); request.QueryString.Returns(new QueryString("?allocationStatuses=Published,Approved")); //Act IActionResult result = await service.GetNotifications(request, pageRef : 3, allocationStatuses : new[] { "Published", "Approved" }); //Assert result .Should() .BeOfType <BadRequestResult>(); }
public async Task GetNotifications_GivenSearchFeedReturnsNoResultsForTheGivenPage_ReturnsNotFoundResult() { //Arrange SearchFeedV2 <AllocationNotificationFeedIndex> feeds = new SearchFeedV2 <AllocationNotificationFeedIndex>() { TotalCount = 1000, Entries = Enumerable.Empty <AllocationNotificationFeedIndex>() }; IAllocationNotificationsFeedsSearchService feedsSearchService = CreateSearchService(); feedsSearchService .GetFeedsV2(Arg.Is(3), Arg.Is(500), statuses: Arg.Any <IEnumerable <string> >()) .Returns(feeds); AllocationNotificationFeedsService service = CreateService(feedsSearchService); HttpRequest request = Substitute.For <HttpRequest>(); //Act IActionResult result = await service.GetNotifications(request, pageRef : 3, allocationStatuses : new[] { "Published", "Approved" }); //Assert result .Should() .BeOfType <NotFoundResult>(); }
public async Task GetFeedsV2_GivenMultipleFilters_SearchesWithFilter() { //Arrange int pageRef = 1; int top = 0; IEnumerable <string> statuses = new[] { "Published", "Approved" }; ISearchRepository <AllocationNotificationFeedIndex> searchRepository = CreateSearchRepository(); AllocationNotificationsFeedsSearchService searchService = CreateSearchService(searchRepository); //Act SearchFeedV2 <AllocationNotificationFeedIndex> searchFeed = await searchService.GetFeedsV2(pageRef, top, 2018, 2019, new[] { "12345678" }, new[] { "laCode" }, true, statuses, new[] { "PSG", "AAL" }, new[] { "PSG-001", "PSG-002" }); //Assert await searchRepository .Received(1) .Search(Arg.Is(""), Arg.Is <SearchParameters>(m => m.Filter == "(allocationStatus eq 'Published' or allocationStatus eq 'Approved') and (fundingStreamId eq 'PSG' or fundingStreamId eq 'AAL') and (allocationLineId eq 'PSG-001' or allocationLineId eq 'PSG-002') and (fundingPeriodStartYear eq 2018) and (fundingPeriodEndYear eq 2019) and (providerUkprn eq '12345678') and (laCode eq 'laCode') and (allocationLineContractRequired eq true)")); }
public async Task GetFeeds_GivenNullPageRef_RetrievesLastPageOfFeedAndPerformsActualSearchAfter() { //Arrange int?pageRef = null; int top = 2; SearchResults <AllocationNotificationFeedIndex> searchResultsForCount = new SearchResults <AllocationNotificationFeedIndex>() { TotalCount = 20, Results = new List <CalculateFunding.Repositories.Common.Search.SearchResult <AllocationNotificationFeedIndex> >() }; SearchResults <AllocationNotificationFeedIndex> searchResults = new SearchResults <AllocationNotificationFeedIndex> { TotalCount = 20, Results = new List <CalculateFunding.Repositories.Common.Search.SearchResult <AllocationNotificationFeedIndex> > { new CalculateFunding.Repositories.Common.Search.SearchResult <AllocationNotificationFeedIndex> { Result = new AllocationNotificationFeedIndex() }, new CalculateFunding.Repositories.Common.Search.SearchResult <AllocationNotificationFeedIndex> { Result = new AllocationNotificationFeedIndex() } } }; ISearchRepository <AllocationNotificationFeedIndex> searchRepository = CreateSearchRepository(); searchRepository .Search(Arg.Is(""), Arg.Is <SearchParameters>(sp => sp.Top == 0)) .Returns(searchResultsForCount); searchRepository .Search(Arg.Is(""), Arg.Is <SearchParameters>(sp => sp.Top == 2)) .Returns(searchResults); AllocationNotificationsFeedsSearchService searchService = CreateSearchService(searchRepository); //Act SearchFeedV2 <AllocationNotificationFeedIndex> searchFeed = await searchService.GetFeedsV2(pageRef, top, statuses : new[] { "Published", "Approved" }); //Assert searchFeed.Should().NotBeNull(); searchFeed.Id.Should().NotBeEmpty(); searchFeed.PageRef.Should().Be(10); searchFeed.Top.Should().Be(2); searchFeed.TotalCount.Should().Be(20); searchFeed.TotalPages.Should().Be(10); searchFeed.Current.Should().Be(null); searchFeed.Last.Should().Be(10); searchFeed.NextArchive.Should().BeNull(); searchFeed.PreviousArchive.Should().Be(9); searchFeed.Entries.Count().Should().Be(2); }
public void GenerateAtomLinksForResultGivenBaseUrl_WhenOnAMiddlePage_ShouldReturnCorrectGeneratedValues() { // arrange SearchFeedV2 <string> searchFeedV2 = new SearchFeedV2 <string> { Top = 10, TotalCount = 50, PageRef = 3 }; // act IList <AtomLink> atomLinksForFeed = searchFeedV2.GenerateAtomLinksForResultGivenBaseUrl("https://localhost:5009/api/v2/allocations/notifications{0}"); // assert atomLinksForFeed .Count .Should().Be(4); var atomLink1 = atomLinksForFeed.First(); atomLink1 .Href .Should().Be("https://localhost:5009/api/v2/allocations/notifications/2"); atomLink1 .Rel .Should().Be("prev-archive"); var atomLink2 = atomLinksForFeed.ElementAt(1); atomLink2 .Href .Should().Be("https://localhost:5009/api/v2/allocations/notifications/4"); atomLink2 .Rel .Should().Be("next-archive"); var atomLink3 = atomLinksForFeed.ElementAt(2); atomLink3 .Href .Should().Be("https://localhost:5009/api/v2/allocations/notifications/3"); atomLink3 .Rel .Should().Be("current"); var atomLink4 = atomLinksForFeed.ElementAt(3); atomLink4 .Href .Should().Be("https://localhost:5009/api/v2/allocations/notifications"); atomLink4 .Rel .Should().Be("self"); }
public async Task GetNotifications_GivenSearchFeedReturnsResultsWhenNoQueryParameters_EnsuresAtomLinksCorrect() { //Arrange SearchFeedV2 <AllocationNotificationFeedIndex> feeds = new SearchFeedV2 <AllocationNotificationFeedIndex> { PageRef = 2, Top = 2, TotalCount = 8, Entries = CreateFeedIndexes() }; IAllocationNotificationsFeedsSearchService feedsSearchService = CreateSearchService(); feedsSearchService .GetFeedsV2(Arg.Is(2), Arg.Is(2)) .ReturnsForAnyArgs(feeds); AllocationNotificationFeedsService service = CreateService(feedsSearchService); IHeaderDictionary headerDictionary = new HeaderDictionary(); headerDictionary.Add("Accept", new StringValues("application/json")); HttpRequest request = Substitute.For <HttpRequest>(); request.Scheme.Returns("https"); request.Path.Returns(new PathString("/api/v2/allocations/notifications/2")); request.Host.Returns(new HostString("wherever.naf:12345")); request.Headers.Returns(headerDictionary); //Act IActionResult result = await service.GetNotifications(request, pageSize : 2, pageRef : 2); //Assert result .Should() .BeOfType <ContentResult>(); ContentResult contentResult = result as ContentResult; AtomFeed <AllocationModel> atomFeed = JsonConvert.DeserializeObject <AtomFeed <AllocationModel> >(contentResult.Content); atomFeed .Should() .NotBeNull(); atomFeed.Id.Should().NotBeEmpty(); atomFeed.Title.Should().Be("Calculate Funding Service Allocation Feed"); atomFeed.Author.Name.Should().Be("Calculate Funding Service"); atomFeed.Link.First(m => m.Rel == "prev-archive").Href.Should().Be("https://wherever.naf:12345/api/v2/allocations/notifications/1"); atomFeed.Link.First(m => m.Rel == "next-archive").Href.Should().Be("https://wherever.naf:12345/api/v2/allocations/notifications/3"); atomFeed.Link.First(m => m.Rel == "current").Href.Should().Be("https://wherever.naf:12345/api/v2/allocations/notifications/2"); atomFeed.Link.First(m => m.Rel == "self").Href.Should().Be("https://wherever.naf:12345/api/v2/allocations/notifications"); }
private static SearchFeedV2 <AllocationNotificationFeedIndex> CreateSearchFeedResult(int?pageRef, int top, SearchResults <AllocationNotificationFeedIndex> searchResults) { SearchFeedV2 <AllocationNotificationFeedIndex> searchFeedResult = new SearchFeedV2 <AllocationNotificationFeedIndex> { Top = top, TotalCount = searchResults != null && searchResults.TotalCount.HasValue ? (int)searchResults?.TotalCount : 0, Entries = searchResults?.Results.Select(m => m.Result) }; if (pageRef.HasValue) { searchFeedResult.PageRef = pageRef.Value; } return(searchFeedResult); }
public async Task GetFeedsV2_GivenFilterValues_SearchesWithNoFilter() { //Arrange int pageRef = 1; int top = 0; ISearchRepository <AllocationNotificationFeedIndex> searchRepository = CreateSearchRepository(); AllocationNotificationsFeedsSearchService searchService = CreateSearchService(searchRepository); //Act SearchFeedV2 <AllocationNotificationFeedIndex> searchFeed = await searchService.GetFeedsV2(pageRef, top); //Assert await searchRepository .Received(1) .Search(Arg.Is(""), Arg.Is <SearchParameters>(m => m.Filter == "")); }
public async Task GetFeedsV2_GivenInvalidTopPassed_DefaultsTopTo500() { //Arrange int pageRef = 1; int top = 0; ISearchRepository <AllocationNotificationFeedIndex> searchRepository = CreateSearchRepository(); AllocationNotificationsFeedsSearchService searchService = CreateSearchService(searchRepository); //Act SearchFeedV2 <AllocationNotificationFeedIndex> searchFeed = await searchService.GetFeedsV2(pageRef, top); //Assert await searchRepository .Received(1) .Search(Arg.Is(""), Arg.Is <SearchParameters>(m => m.Top == 500 && m.OrderBy.First() == "dateUpdated asc")); }
private AtomFeed <AllocationModel> CreateAtomFeed(SearchFeedV2 <AllocationNotificationFeedIndex> searchFeed, HttpRequest request) { const string notificationsEndpointName = "notifications"; string baseRequestPath = request.Path.Value.Substring(0, request.Path.Value.IndexOf(notificationsEndpointName, StringComparison.Ordinal) + notificationsEndpointName.Length); string allocationTrimmedRequestPath = baseRequestPath.Replace(notificationsEndpointName, string.Empty).TrimEnd('/'); string queryString = request.QueryString.Value; string notificationsUrl = $"{request.Scheme}://{request.Host.Value}{baseRequestPath}{{0}}{(!string.IsNullOrWhiteSpace(queryString) ? queryString : "")}"; AtomFeed <AllocationModel> atomFeed = new AtomFeed <AllocationModel> { Id = Guid.NewGuid().ToString("N"), Title = "Calculate Funding Service Allocation Feed", Author = new AtomAuthor { Name = "Calculate Funding Service", Email = "*****@*****.**" }, Updated = DateTimeOffset.Now, Rights = "Copyright (C) 2019 Department for Education", Link = searchFeed.GenerateAtomLinksForResultGivenBaseUrl(notificationsUrl).ToList(), AtomEntry = new List <AtomEntry <AllocationModel> >(), IsArchived = searchFeed.IsArchivePage }; foreach (AllocationNotificationFeedIndex feedIndex in searchFeed.Entries) { ProviderVariation providerVariation = new ProviderVariation(); if (!feedIndex.VariationReasons.IsNullOrEmpty()) { providerVariation.VariationReasons = new Collection <string>(feedIndex.VariationReasons); } if (!feedIndex.Successors.IsNullOrEmpty()) { List <ProviderInformationModel> providerInformationModels = feedIndex.Successors.Select(fi => new ProviderInformationModel() { Ukprn = fi }).ToList(); providerVariation.Successors = new Collection <ProviderInformationModel>(providerInformationModels); } if (!feedIndex.Predecessors.IsNullOrEmpty()) { List <ProviderInformationModel> providerInformationModels = feedIndex.Predecessors.Select(fi => new ProviderInformationModel() { Ukprn = fi }).ToList(); providerVariation.Predecessors = new Collection <ProviderInformationModel>(providerInformationModels); } providerVariation.OpenReason = feedIndex.OpenReason; providerVariation.CloseReason = feedIndex.CloseReason; atomFeed.AtomEntry.Add(new AtomEntry <AllocationModel> { Id = $"{request.Scheme}://{request.Host.Value}{allocationTrimmedRequestPath}/{feedIndex.Id}", Title = feedIndex.Title, Summary = feedIndex.Summary, Published = feedIndex.DatePublished, Updated = feedIndex.DateUpdated.Value, Version = $"{feedIndex.MajorVersion}.{feedIndex.MinorVersion}", Link = new AtomLink("Allocation", $"{ request.Scheme }://{request.Host.Value}{allocationTrimmedRequestPath}/{feedIndex.Id}"), Content = new AtomContent <AllocationModel> { Allocation = new AllocationModel { FundingStream = new AllocationFundingStreamModel { Id = feedIndex.FundingStreamId, Name = feedIndex.FundingStreamName, ShortName = feedIndex.FundingStreamShortName, PeriodType = new AllocationFundingStreamPeriodTypeModel { Id = feedIndex.FundingStreamPeriodId, Name = feedIndex.FundingStreamPeriodName, StartDay = feedIndex.FundingStreamStartDay, StartMonth = feedIndex.FundingStreamStartMonth, EndDay = feedIndex.FundingStreamEndDay, EndMonth = feedIndex.FundingStreamEndMonth } }, Period = new Period { Id = feedIndex.FundingPeriodId, Name = feedIndex.FundingStreamPeriodName, StartYear = feedIndex.FundingPeriodStartYear, EndYear = feedIndex.FundingPeriodEndYear }, Provider = new AllocationProviderModel { Name = feedIndex.ProviderName, LegalName = feedIndex.ProviderLegalName, UkPrn = feedIndex.ProviderUkPrn, Upin = feedIndex.ProviderUpin, Urn = feedIndex.ProviderUrn, DfeEstablishmentNumber = feedIndex.DfeEstablishmentNumber, EstablishmentNumber = feedIndex.EstablishmentNumber, LaCode = feedIndex.LaCode, LocalAuthority = feedIndex.Authority, Type = feedIndex.ProviderType, SubType = feedIndex.SubProviderType, OpenDate = feedIndex.ProviderOpenDate, CloseDate = feedIndex.ProviderClosedDate, CrmAccountId = feedIndex.CrmAccountId, NavVendorNo = feedIndex.NavVendorNo, Status = feedIndex.ProviderStatus, ProviderId = feedIndex.ProviderId, ProviderVariation = providerVariation }, AllocationLine = new AllocationLine { Id = feedIndex.AllocationLineId, Name = feedIndex.AllocationLineName, ShortName = feedIndex.AllocationLineShortName, FundingRoute = feedIndex.AllocationLineFundingRoute, ContractRequired = feedIndex.AllocationLineContractRequired ? "Y" : "N" }, AllocationMajorVersion = feedIndex.MajorVersion ?? 0, AllocationMinorVersion = feedIndex.MinorVersion ?? 0, AllocationStatus = feedIndex.AllocationStatus, AllocationAmount = (decimal)feedIndex.AllocationAmount, AllocationResultId = feedIndex.Id, AllocationResultTitle = feedIndex.Title, ProfilePeriods = string.IsNullOrEmpty(feedIndex.ProviderProfiling) ? new List <ProfilePeriod>() : new List <ProfilePeriod>(JsonConvert .DeserializeObject <IEnumerable <ProfilingPeriod> >(feedIndex.ProviderProfiling) .Select(m => new ProfilePeriod(m.Period, m.Occurrence, m.Year.ToString(), m.Type, m.Value, m.DistributionPeriod)) .ToArraySafe()) } } }); } return(atomFeed); }
public async Task GetNotifications_GivenMajorMinorFeatureToggleOn_ReturnsMajorMinorVersionNumbers() { //Arrange SearchFeedV2 <AllocationNotificationFeedIndex> feeds = new SearchFeedV2 <AllocationNotificationFeedIndex> { PageRef = 3, Top = 500, TotalCount = 3, Entries = CreateFeedIndexes() }; IAllocationNotificationsFeedsSearchService feedsSearchService = CreateSearchService(); feedsSearchService .GetFeedsV2(Arg.Is(3), Arg.Is(2)) .ReturnsForAnyArgs(feeds); AllocationNotificationFeedsService service = CreateService(feedsSearchService); IHeaderDictionary headerDictionary = new HeaderDictionary { { "Accept", new StringValues("application/json") } }; IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "pageRef", new StringValues("3") }, { "allocationStatuses", new StringValues("Published,Approved") }, { "pageSize", new StringValues("2") } }); HttpRequest request = Substitute.For <HttpRequest>(); request.Scheme.Returns("https"); request.Path.Returns(new PathString("/api/v1/test")); request.Host.Returns(new HostString("wherever.naf:12345")); request.QueryString.Returns(new QueryString("?pageRef=3&pageSize=2&allocationStatuses=Published,Approved")); request.Headers.Returns(headerDictionary); request.Query.Returns(queryStringValues); //Act IActionResult result = await service.GetNotifications(request, pageRef : 3, pageSize : 2, allocationStatuses : new[] { "Published", "Approved" }); //Assert result .Should() .BeOfType <ContentResult>(); ContentResult contentResult = result as ContentResult; AtomFeed <AllocationModel> atomFeed = JsonConvert.DeserializeObject <AtomFeed <AllocationModel> >(contentResult.Content); atomFeed .Should() .NotBeNull(); atomFeed.Id.Should().NotBeEmpty(); atomFeed.AtomEntry.Count.Should().Be(3); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.AllocationMajorVersion.Should().Be(1); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.AllocationMinorVersion.Should().Be(0); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.AllocationMajorVersion.Should().Be(2); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.AllocationMinorVersion.Should().Be(0); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.AllocationMajorVersion.Should().Be(0); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.AllocationMinorVersion.Should().Be(3); }
public async Task GetNotifications_GivenAQueryStringForWhichThereAreResults_ReturnsAtomFeedWithCorrectLinks() { //Arrange SearchFeedV2 <AllocationNotificationFeedIndex> feeds = new SearchFeedV2 <AllocationNotificationFeedIndex> { PageRef = 2, Top = 2, TotalCount = 8, Entries = CreateFeedIndexes() }; AllocationNotificationFeedIndex firstFeedItem = feeds.Entries.ElementAt(0); firstFeedItem.VariationReasons = new[] { "LegalNameFieldUpdated", "LACodeFieldUpdated" }; firstFeedItem.Successors = new[] { "provider4" }; firstFeedItem.Predecessors = new[] { "provider1", "provider2" }; firstFeedItem.OpenReason = "Fresh Start"; firstFeedItem.CloseReason = "Closure"; IAllocationNotificationsFeedsSearchService feedsSearchService = CreateSearchService(); feedsSearchService .GetFeedsV2(Arg.Is(2), Arg.Is(2)) .ReturnsForAnyArgs(feeds); AllocationNotificationFeedsService service = CreateService(feedsSearchService); IHeaderDictionary headerDictionary = new HeaderDictionary(); headerDictionary.Add("Accept", new StringValues("application/json")); IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "pageRef", new StringValues("2") }, { "allocationStatuses", new StringValues("Published,Approved") }, { "pageSize", new StringValues("2") } }); HttpRequest request = Substitute.For <HttpRequest>(); request.Scheme.Returns("https"); request.Path.Returns(new PathString("/api/v2/allocations/notifications")); request.Host.Returns(new HostString("wherever.naf:12345")); request.QueryString.Returns(new QueryString("?pageSize=2&allocationStatuses=Published&allocationStatuses=Approved")); request.Headers.Returns(headerDictionary); request.Query.Returns(queryStringValues); //Act IActionResult result = await service.GetNotifications(request, pageRef : 2, pageSize : 2, allocationStatuses : new[] { "Published", "Approved" }); //Assert result .Should() .BeOfType <ContentResult>(); ContentResult contentResult = result as ContentResult; AtomFeed <AllocationModel> atomFeed = JsonConvert.DeserializeObject <AtomFeed <AllocationModel> >(contentResult.Content); atomFeed .Should() .NotBeNull(); atomFeed.Id.Should().NotBeEmpty(); atomFeed.Title.Should().Be("Calculate Funding Service Allocation Feed"); atomFeed.Author.Name.Should().Be("Calculate Funding Service"); atomFeed.Link.First(m => m.Rel == "next-archive").Href.Should().Be("https://wherever.naf:12345/api/v2/allocations/notifications/3?pageSize=2&allocationStatuses=Published&allocationStatuses=Approved"); atomFeed.Link.First(m => m.Rel == "prev-archive").Href.Should().Be("https://wherever.naf:12345/api/v2/allocations/notifications/1?pageSize=2&allocationStatuses=Published&allocationStatuses=Approved"); atomFeed.Link.First(m => m.Rel == "self").Href.Should().Be("https://wherever.naf:12345/api/v2/allocations/notifications?pageSize=2&allocationStatuses=Published&allocationStatuses=Approved"); atomFeed.Link.First(m => m.Rel == "current").Href.Should().Be("https://wherever.naf:12345/api/v2/allocations/notifications/2?pageSize=2&allocationStatuses=Published&allocationStatuses=Approved"); atomFeed.AtomEntry.Count.Should().Be(3); atomFeed.AtomEntry.ElementAt(0).Id.Should().Be("https://wherever.naf:12345/api/v2/allocations/id-1"); atomFeed.AtomEntry.ElementAt(0).Title.Should().Be("test title 1"); atomFeed.AtomEntry.ElementAt(0).Summary.Should().Be("test summary 1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.FundingStream.Id.Should().Be("fs-1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.FundingStream.Name.Should().Be("fs 1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Period.Id.Should().Be("fp-1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.UkPrn.Should().Be("1111"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.Upin.Should().Be("0001"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.AllocationLine.Id.Should().Be("al-1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.AllocationLine.Name.Should().Be("al 1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.AllocationStatus.Should().Be("Published"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.AllocationAmount.Should().Be(10); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.ProfilePeriods.Should().HaveCount(0); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.FundingStream.ShortName.Should().Be("fs-short-1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.FundingStream.PeriodType.Id.Should().Be("fspi-1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.FundingStream.PeriodType.Name.Should().Be("fspi1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.FundingStream.PeriodType.StartDay.Should().Be(1); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.FundingStream.PeriodType.StartMonth.Should().Be(8); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.FundingStream.PeriodType.EndDay.Should().Be(31); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.FundingStream.PeriodType.EndMonth.Should().Be(7); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Period.Name.Should().Be("fspi1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Period.StartYear.Should().Be(2018); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Period.EndYear.Should().Be(2019); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.Name.Should().Be("provider 1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.LegalName.Should().Be("legal 1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.Urn.Should().Be("01"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.DfeEstablishmentNumber.Should().Be("dfe-1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.EstablishmentNumber.Should().Be("e-1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.LaCode.Should().Be("la-1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.LocalAuthority.Should().Be("authority"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.Type.Should().Be("type 1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.SubType.Should().Be("sub type 1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.OpenDate.Should().NotBeNull(); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.CloseDate.Should().NotBeNull(); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.CrmAccountId.Should().Be("crm-1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.NavVendorNo.Should().Be("nv-1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.Status.Should().Be("Active"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.AllocationLine.ShortName.Should().Be("short-al1"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.AllocationLine.FundingRoute.Should().Be("LA"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.AllocationLine.ContractRequired.Should().Be("Y"); atomFeed.AtomEntry.ElementAt(0).Content.Allocation.AllocationResultTitle.Should().Be("test title 1"); ProviderVariation providerVariation1 = atomFeed.AtomEntry.ElementAt(0).Content.Allocation.Provider.ProviderVariation; providerVariation1.Should().NotBeNull(); providerVariation1.VariationReasons.Should().BeEquivalentTo("LegalNameFieldUpdated", "LACodeFieldUpdated"); providerVariation1.Successors.First().Ukprn.Should().Be("provider4"); providerVariation1.Predecessors.First().Ukprn.Should().Be("provider1"); providerVariation1.Predecessors[1].Ukprn.Should().Be("provider2"); providerVariation1.OpenReason.Should().Be("Fresh Start"); providerVariation1.CloseReason.Should().Be("Closure"); atomFeed.AtomEntry.ElementAt(1).Id.Should().Be("https://wherever.naf:12345/api/v2/allocations/id-2"); atomFeed.AtomEntry.ElementAt(1).Title.Should().Be("test title 2"); atomFeed.AtomEntry.ElementAt(1).Summary.Should().Be("test summary 2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.FundingStream.Id.Should().Be("fs-2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.FundingStream.Name.Should().Be("fs 2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Period.Id.Should().Be("fp-2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.UkPrn.Should().Be("2222"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.Upin.Should().Be("0002"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.AllocationLine.Id.Should().Be("al-2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.AllocationLine.Name.Should().Be("al 2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.AllocationStatus.Should().Be("Published"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.AllocationAmount.Should().Be(100); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.ProfilePeriods.Should().HaveCount(2); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.FundingStream.ShortName.Should().Be("fs-short-2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.FundingStream.PeriodType.Id.Should().Be("fspi-2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.FundingStream.PeriodType.Name.Should().Be("fspi2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.FundingStream.PeriodType.StartDay.Should().Be(1); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.FundingStream.PeriodType.StartMonth.Should().Be(8); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.FundingStream.PeriodType.EndDay.Should().Be(31); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.FundingStream.PeriodType.EndMonth.Should().Be(7); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Period.Name.Should().Be("fspi2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Period.StartYear.Should().Be(2018); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Period.EndYear.Should().Be(2019); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.Name.Should().Be("provider 2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.LegalName.Should().Be("legal 2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.Urn.Should().Be("02"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.DfeEstablishmentNumber.Should().Be("dfe-2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.EstablishmentNumber.Should().Be("e-2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.LaCode.Should().Be("la-2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.LocalAuthority.Should().Be("authority"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.Type.Should().Be("type 2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.SubType.Should().Be("sub type 2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.OpenDate.Should().NotBeNull(); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.CloseDate.Should().NotBeNull(); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.CrmAccountId.Should().Be("crm-2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.NavVendorNo.Should().Be("nv-2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.Status.Should().Be("Active"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.AllocationLine.ShortName.Should().Be("short-al2"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.AllocationLine.FundingRoute.Should().Be("LA"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.AllocationLine.ContractRequired.Should().Be("Y"); atomFeed.AtomEntry.ElementAt(1).Content.Allocation.AllocationResultTitle.Should().Be("test title 2"); ProviderVariation providerVariation2 = atomFeed.AtomEntry.ElementAt(1).Content.Allocation.Provider.ProviderVariation; AssertProviderVariationValuesNotSet(providerVariation2); atomFeed.AtomEntry.ElementAt(2).Id.Should().Be("https://wherever.naf:12345/api/v2/allocations/id-3"); atomFeed.AtomEntry.ElementAt(2).Title.Should().Be("test title 3"); atomFeed.AtomEntry.ElementAt(2).Summary.Should().Be("test summary 3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.FundingStream.Id.Should().Be("fs-3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.FundingStream.Name.Should().Be("fs 3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Period.Id.Should().Be("fp-3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.UkPrn.Should().Be("3333"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.Upin.Should().Be("0003"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.AllocationLine.Id.Should().Be("al-3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.AllocationLine.Name.Should().Be("al 3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.AllocationStatus.Should().Be("Approved"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.AllocationAmount.Should().Be(20); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.ProfilePeriods.Should().HaveCount(0); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.FundingStream.ShortName.Should().Be("fs-short-3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.FundingStream.PeriodType.Id.Should().Be("fspi-3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.FundingStream.PeriodType.StartDay.Should().Be(1); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.FundingStream.PeriodType.StartMonth.Should().Be(8); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.FundingStream.PeriodType.EndDay.Should().Be(31); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.FundingStream.PeriodType.EndMonth.Should().Be(7); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Period.Name.Should().Be("fspi3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Period.StartYear.Should().Be(2018); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Period.EndYear.Should().Be(2019); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.Name.Should().Be("provider 3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.LegalName.Should().Be("legal 3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.Urn.Should().Be("03"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.DfeEstablishmentNumber.Should().Be("dfe-3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.EstablishmentNumber.Should().Be("e-3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.LaCode.Should().Be("la-3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.LocalAuthority.Should().Be("authority"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.Type.Should().Be("type 3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.SubType.Should().Be("sub type 3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.OpenDate.Should().NotBeNull(); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.CloseDate.Should().NotBeNull(); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.CrmAccountId.Should().Be("crm-3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.NavVendorNo.Should().Be("nv-3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.Status.Should().Be("Active"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.AllocationLine.ShortName.Should().Be("short-al3"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.AllocationLine.FundingRoute.Should().Be("LA"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.AllocationLine.ContractRequired.Should().Be("Y"); atomFeed.AtomEntry.ElementAt(2).Content.Allocation.AllocationResultTitle.Should().Be("test title 3"); ProviderVariation providerVariation3 = atomFeed.AtomEntry.ElementAt(2).Content.Allocation.Provider.ProviderVariation; AssertProviderVariationValuesNotSet(providerVariation2); }