private async Task PopulateFundingStreams(IEnumerable <string> fundingStreamIds) { ApiResponse <IEnumerable <FundingStream> > fundingStreamsResponse = await _specsClient.GetFundingStreams(); if (fundingStreamsResponse == null) { throw new InvalidOperationException($"Null funding streams response returned"); } if (fundingStreamsResponse.StatusCode == HttpStatusCode.OK && !fundingStreamsResponse.Content.IsNullOrEmpty()) { // Need to make sure existing funding stream ids on the spec are still included on the list to display in the list as the security trimmed list is based on Create permission not Edit IEnumerable <FundingStream> existingFundingStreams = fundingStreamsResponse.Content.Where(fs => fundingStreamIds.Contains(fs.Id)); IEnumerable <FundingStream> trimmedResults = await _authorizationHelper.SecurityTrimList(User, fundingStreamsResponse.Content, FundingStreamActionTypes.CanCreateSpecification); IEnumerable <FundingStream> fundingStreams = trimmedResults.Union(existingFundingStreams, new FundingStreamComparer()); IEnumerable <SelectListItem> fundingStreamListItems = fundingStreams.Select(m => new SelectListItem { Value = m.Id, Text = m.Name, }).ToList(); FundingStreams = new MultiSelectList(fundingStreamListItems, "Value", "Text", fundingStreamIds); } else { throw new InvalidOperationException($"Unable to retreive Funding Streams. Status Code = {fundingStreamsResponse.StatusCode}"); } }
public async Task OnGetAsync_GivenUserDoesNotHaveCreateSpecificationPermissionForAnyFundingStream_ThenFundingStreamsShouldBeEmpty() { // Arrange IEnumerable <Reference> fundingPeriods = new[] { new Reference { Id = "fp1", Name = "Funding Period 1" }, new Reference { Id = "fp2", Name = "Funding Period 2" } }; IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream { Id = "fp1", Name = "funding" } }; ISpecsApiClient specsClient = Substitute.For <ISpecsApiClient>(); specsClient .GetFundingPeriods() .Returns(new ApiResponse <IEnumerable <Reference> >(HttpStatusCode.OK, fundingPeriods)); specsClient .GetFundingStreams() .Returns(new ApiResponse <IEnumerable <FundingStream> >(HttpStatusCode.OK, fundingStreams)); IAuthorizationHelper authorizationHelper = Substitute.For <IAuthorizationHelper>(); authorizationHelper .SecurityTrimList(Arg.Any <ClaimsPrincipal>(), Arg.Is(fundingStreams), Arg.Is(FundingStreamActionTypes.CanCreateSpecification)) .Returns(Enumerable.Empty <FundingStream>()); CreateSpecificationPageModel pageModel = CreatePageModel(specsClient: specsClient, authorizationHelper: authorizationHelper); // Act IActionResult result = await pageModel.OnGetAsync(); // Assert result.Should().BeOfType <PageResult>(); pageModel.FundingStreams.Should().BeEmpty(); pageModel .IsAuthorizedToCreate .Should().BeFalse(); }
public async Task PopulatePageModel() { ApiResponse <IEnumerable <SpecificationSummary> > apiResponse = await _specsClient.GetSpecificationSummaries(); if (apiResponse.StatusCode != HttpStatusCode.OK && apiResponse.Content == null) { throw new InvalidOperationException($"Unable to retreive Specification information: Status Code = {apiResponse.StatusCode}"); } IEnumerable <SpecificationSummary> trimmedSpecs = await _authorizationHelper.SecurityTrimList(User, apiResponse.Content, SpecificationActionTypes.CanCreateQaTests); IsAuthorizedToCreate = trimmedSpecs.Any(); Specifications = trimmedSpecs.OrderBy(s => s.Name).Select(m => new SelectListItem { Value = m.Id, Text = m.Name }).ToList(); }
private async Task PopulateFundingStreams() { ApiResponse <IEnumerable <FundingStream> > fundingStreamsResponse = await _specsClient.GetFundingStreams(); if (fundingStreamsResponse.StatusCode == HttpStatusCode.OK && !fundingStreamsResponse.Content.IsNullOrEmpty()) { IEnumerable <FundingStream> fundingStreams = await _authorizationHelper.SecurityTrimList(User, fundingStreamsResponse.Content, FundingStreamActionTypes.CanCreateSpecification); FundingStreams = fundingStreams.Select(m => new SelectListItem { Value = m.Id, Text = m.Name }).ToList(); } else { throw new InvalidOperationException($"Unable to retreive Funding Streams. Status Code = {fundingStreamsResponse.StatusCode}"); } }
public async Task <IActionResult> OnGetAsync(string fundingPeriod, string fundingStream, ChoosePageBannerOperationType?operationType = null, string operationId = null) { List <Task> tasks = new List <Task>(); Task <ApiResponse <IEnumerable <SpecificationSummary> > > specificationsLookupTask = null; if (!string.IsNullOrWhiteSpace(fundingPeriod) && !string.IsNullOrWhiteSpace(fundingStream)) { specificationsLookupTask = _specsClient.GetApprovedSpecifications(fundingPeriod, fundingStream); tasks.Add(specificationsLookupTask); } Task <ApiResponse <IEnumerable <Reference> > > fundingPeriodsLookupTask = _specsClient.GetFundingPeriods(); Task <ApiResponse <IEnumerable <FundingStream> > > fundingStreamsLookupTask = _specsClient.GetFundingStreams(); tasks.Add(fundingPeriodsLookupTask); tasks.Add(fundingStreamsLookupTask); await TaskHelper.WhenAllAndThrow(tasks.ToArray()); IActionResult errorResult = fundingPeriodsLookupTask.Result.IsSuccessOrReturnFailureResult("Funding Period"); if (errorResult != null) { return(errorResult); } errorResult = fundingStreamsLookupTask.Result.IsSuccessOrReturnFailureResult("Funding Stream"); if (errorResult != null) { return(errorResult); } FundingStreams = fundingStreamsLookupTask.Result.Content.Select(s => new SelectListItem() { Text = s.Name, Value = s.Id, Selected = fundingStream == s.Id, }); FundingPeriods = fundingPeriodsLookupTask.Result.Content.Select(s => new SelectListItem() { Text = s.Name, Value = s.Id, Selected = fundingPeriod == s.Id, }); Dictionary <string, ChooseApprovalSpecificationViewModel> specifications = new Dictionary <string, ChooseApprovalSpecificationViewModel>(); if (!string.IsNullOrWhiteSpace(fundingPeriod) && !string.IsNullOrWhiteSpace(fundingStream)) { errorResult = specificationsLookupTask.Result.IsSuccessOrReturnFailureResult("Specification"); if (errorResult != null) { return(errorResult); } SelectedFundingPeriodId = fundingPeriod; SelectedFundingStreamId = fundingStream; IEnumerable <SpecificationSummary> specificationSummaries = specificationsLookupTask.Result.Content.ToList(); IEnumerable <SpecificationSummary> specificationSummariesTrimmed = await _authorizationHelper.SecurityTrimList(User, specificationSummaries, SpecificationActionTypes.CanChooseFunding); IEnumerable <SpecificationSummary> specificationSummariesUnauthorizedToChoose = specificationSummaries.Except(specificationSummariesTrimmed); IsSpecificationSelectedForThisFunding = specificationSummaries.Any(sc => sc.IsSelectedForFunding); IEnumerable <ChooseApprovalSpecificationViewModel> specificationsAuthorizedViewModel = ConvertToChooseApprovalSpecificationModelWithCanBeChosenFlag(specificationSummariesTrimmed, !IsSpecificationSelectedForThisFunding); IEnumerable <ChooseApprovalSpecificationViewModel> specificationsUnauthorizedViewModel = ConvertToChooseApprovalSpecificationModelWithCanBeChosenFlag(specificationSummariesUnauthorizedToChoose, false); ShouldDisplayPermissionsBanner = specificationsUnauthorizedViewModel.Any(); IEnumerable <ChooseApprovalSpecificationViewModel> specificationViewModels = specificationsAuthorizedViewModel.Concat(specificationsUnauthorizedViewModel); specifications = specificationViewModels.ToDictionary(vm => vm.Id); } if (specifications.Count > 0) { SpecificationIdsRequestModel specificationIdsRequest = new SpecificationIdsRequestModel() { SpecificationIds = specifications.Keys, }; Task <ApiResponse <IEnumerable <CalculationStatusCounts> > > calculationStatusCountsLookupTask = _calcsClient.GetCalculationStatusCounts(specificationIdsRequest); Task <ApiResponse <IEnumerable <FundingCalculationResultsTotals> > > resultTotalsCountsLookupTask = _resultsClient.GetFundingCalculationResultsTotals(specificationIdsRequest); Task <ApiResponse <IEnumerable <SpecificationTestScenarioResultCounts> > > testScenarioResultCountsLookupTask = _testEngineClient.GetTestScenarioCountsForSpecifications(specificationIdsRequest); await TaskHelper.WhenAllAndThrow(calculationStatusCountsLookupTask, resultTotalsCountsLookupTask, testScenarioResultCountsLookupTask); errorResult = calculationStatusCountsLookupTask.Result.IsSuccessOrReturnFailureResult("Calculation Status Counts"); if (errorResult != null) { return(errorResult); } errorResult = resultTotalsCountsLookupTask.Result.IsSuccessOrReturnFailureResult("Calculation Result"); if (errorResult != null) { return(errorResult); } errorResult = testScenarioResultCountsLookupTask.Result.IsSuccessOrReturnFailureResult("Test Scenario Counts"); if (errorResult != null) { return(errorResult); } if (calculationStatusCountsLookupTask.Result.Content.Count() != specificationIdsRequest.SpecificationIds.Count()) { return(new InternalServerErrorResult($"Number of calculation approvals counts ({calculationStatusCountsLookupTask.Result.Content.Count()} does not match number of specifications requested ({specificationIdsRequest.SpecificationIds.Count()}")); } foreach (CalculationStatusCounts counts in calculationStatusCountsLookupTask.Result.Content) { ChooseApprovalSpecificationViewModel chooseVm = specifications[counts.SpecificationId]; chooseVm.CalculationsApproved = counts.Approved; chooseVm.CalculationsTotal = counts.Total; } if (resultTotalsCountsLookupTask.Result.Content.Count() != specificationIdsRequest.SpecificationIds.Count()) { return(new InternalServerErrorResult($"Number of calculation result counts ({resultTotalsCountsLookupTask.Result.Content.Count()} does not match number of specifications requested ({specificationIdsRequest.SpecificationIds.Count()}")); } foreach (FundingCalculationResultsTotals counts in resultTotalsCountsLookupTask.Result.Content) { ChooseApprovalSpecificationViewModel chooseVm = specifications[counts.SpecificationId]; chooseVm.FundingAmount = counts.TotalResult; } if (testScenarioResultCountsLookupTask.Result.Content.Count() != specificationIdsRequest.SpecificationIds.Count()) { return(new InternalServerErrorResult($"Number of test scenario result counts ({testScenarioResultCountsLookupTask.Result.Content.Count()} does not match number of specifications requested ({specificationIdsRequest.SpecificationIds.Count()}")); } foreach (SpecificationTestScenarioResultCounts counts in testScenarioResultCountsLookupTask.Result.Content) { ChooseApprovalSpecificationViewModel chooseVm = specifications[counts.SpecificationId]; chooseVm.QaTestsPassed = counts.Passed; chooseVm.QaTestsTotal = counts.Passed + counts.Ignored + counts.Failed; chooseVm.ProviderQaCoverage = counts.TestCoverage; } } Specifications = specifications.Values.AsEnumerable(); if (operationType.HasValue && specifications.ContainsKey(operationId)) { ChooseApprovalSpecificationViewModel specification = specifications[operationId]; PageBannerOperation = new PageBannerOperation() { EntityName = specification.Name, EntityType = "Specification", OperationAction = "chosen for funding", OperationId = operationId, ActionText = "View funding", ActionUrl = "/approvals/viewfunding/" + specification.Id }; } return(Page()); }
public async Task <IActionResult> GetApprovedSpecificationsTrimmed(string fundingPeriodId, string fundingStreamId) { Guard.IsNullOrWhiteSpace(fundingPeriodId, nameof(fundingPeriodId)); Guard.IsNullOrWhiteSpace(fundingStreamId, nameof(fundingStreamId)); ApiResponse <IEnumerable <SpecificationSummary> > apiResponse = await _specificationsApiClient.GetApprovedSpecificationsByFundingPeriodIdAndFundingStreamId(fundingPeriodId, fundingStreamId); if (apiResponse.StatusCode == HttpStatusCode.OK) { IEnumerable <SpecificationSummary> specificationSummaries = apiResponse.Content; IEnumerable <SpecificationSummary> specificationSummariesTrimmed = await _authorizationHelper.SecurityTrimList(User, specificationSummaries, SpecificationActionTypes.CanChooseFunding); return(Ok(specificationSummaries.OrderBy(c => c.Name).Select(_ => (_, specificationSummariesTrimmed.Any(trimmedSpec => trimmedSpec.Id == _.Id) == true ? true : false)))); } if (apiResponse.StatusCode == HttpStatusCode.BadRequest) { return(new BadRequestResult()); } return(new StatusCodeResult(500)); }
public async Task OnPostAsync_GivenPagePopulatesButModelStateIsInvalid_ReturnsPage() { //Arrange const string specName = "spec name"; IEnumerable <Reference> fundingPeriods = new[] { new Reference { Id = "fp1", Name = "funding" } }; IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream { Id = "fp1", Name = "funding" } }; ApiResponse <Specification> existingSpecificationResponse = new ApiResponse <Specification>(HttpStatusCode.OK); ApiResponse <IEnumerable <Reference> > fundingPeriodsResponse = new ApiResponse <IEnumerable <Reference> >(HttpStatusCode.OK, fundingPeriods); ApiResponse <IEnumerable <FundingStream> > fundingStreamsResponse = new ApiResponse <IEnumerable <FundingStream> >(HttpStatusCode.OK, fundingStreams); ISpecsApiClient apiClient = CreateApiClient(); apiClient .GetSpecificationByName(Arg.Is(specName)) .Returns(existingSpecificationResponse); apiClient .GetFundingPeriods() .Returns(fundingPeriodsResponse); apiClient .GetFundingStreams() .Returns(fundingStreamsResponse); IAuthorizationHelper authorizationHelper = Substitute.For <IAuthorizationHelper>(); authorizationHelper .SecurityTrimList(Arg.Any <ClaimsPrincipal>(), Arg.Is(fundingStreams), Arg.Is(FundingStreamActionTypes.CanCreateSpecification)) .Returns(fundingStreams); CreateSpecificationPageModel pageModel = CreatePageModel(specsClient: apiClient, authorizationHelper: authorizationHelper); pageModel.CreateSpecificationViewModel = new CreateSpecificationViewModel { Name = specName }; pageModel.PageContext.ModelState.AddModelError("test", "Invalid model"); //Act IActionResult result = await pageModel.OnPostAsync(); //Assert result .Should() .BeOfType <PageResult>(); pageModel .FundingStreams .Count() .Should() .Be(1); pageModel .FundingPeriods .Count() .Should() .Be(1); pageModel .IsAuthorizedToCreate .Should().BeTrue(); }
public async Task OnGetAsync_GivenPagePopulatesAndPeriodIdProvided_ReturnsPageSetsPeriodInSelectAsDefault() { //Arrange IEnumerable <Reference> fundingPeriods = new[] { new Reference { Id = "fp1", Name = "Funding Period 1" }, new Reference { Id = "fp2", Name = "Funding Period 2" } }; IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream { Id = "fp1", Name = "funding" } }; ApiResponse <IEnumerable <Reference> > fundingPeriodsResponse = new ApiResponse <IEnumerable <Reference> >(HttpStatusCode.OK, fundingPeriods); ApiResponse <IEnumerable <FundingStream> > fundingStreamsResponse = new ApiResponse <IEnumerable <FundingStream> >(HttpStatusCode.OK, fundingStreams); ISpecsApiClient apiClient = CreateApiClient(); apiClient .GetFundingPeriods() .Returns(fundingPeriodsResponse); apiClient .GetFundingStreams() .Returns(fundingStreamsResponse); IAuthorizationHelper authorizationHelper = Substitute.For <IAuthorizationHelper>(); authorizationHelper .SecurityTrimList(Arg.Any <ClaimsPrincipal>(), Arg.Is(fundingStreams), Arg.Is(FundingStreamActionTypes.CanCreateSpecification)) .Returns(fundingStreams); CreateSpecificationPageModel pageModel = CreatePageModel(specsClient: apiClient, authorizationHelper: authorizationHelper); //Act IActionResult result = await pageModel.OnGetAsync("fp2"); //Assert result .Should() .BeOfType <PageResult>(); pageModel .FundingStreams .Count() .Should() .Be(1); pageModel .FundingPeriods .Count() .Should() .Be(2); pageModel .IsAuthorizedToCreate .Should().BeTrue(); pageModel .FundingPeriods .First(m => m.Value == "fp2") .Selected .Should() .BeTrue(); }
public async Task OnPostAsync_GivenPagePopulatesButModelStateIsInvalid_ReturnsPage() { //Arrange IEnumerable <Reference> fundingPeriods = new[] { new Reference { Id = "fp1", Name = "funding" } }; IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream { Id = "fs1", Name = "funding stream" } }; ApiResponse <Specification> existingSpecificationResponse = new ApiResponse <Specification>(HttpStatusCode.OK); ApiResponse <IEnumerable <Reference> > fundingPeriodsResponse = new ApiResponse <IEnumerable <Reference> >(HttpStatusCode.OK, fundingPeriods); ApiResponse <IEnumerable <FundingStream> > fundingStreamsResponse = new ApiResponse <IEnumerable <FundingStream> >(HttpStatusCode.OK, fundingStreams); ISpecsApiClient apiClient = CreateApiClient(); apiClient .GetSpecificationByName(Arg.Is(specName)) .Returns(existingSpecificationResponse); apiClient .GetFundingPeriods() .Returns(fundingPeriodsResponse); apiClient .GetFundingStreams() .Returns(fundingStreamsResponse); IAuthorizationHelper authorizationHelper = Substitute.For <IAuthorizationHelper>(); authorizationHelper .DoesUserHavePermission(Arg.Any <ClaimsPrincipal>(), Arg.Any <ISpecificationAuthorizationEntity>(), Arg.Is(SpecificationActionTypes.CanEditSpecification)) .Returns(true); authorizationHelper .SecurityTrimList(Arg.Any <ClaimsPrincipal>(), Arg.Is(fundingStreams), Arg.Is(FundingStreamActionTypes.CanCreateSpecification)) .Returns(fundingStreams); EditSpecificationPageModel pageModel = CreatePageModel(specsClient: apiClient, authorizationHelper: authorizationHelper); pageModel.EditSpecificationViewModel = new EditSpecificationViewModel { Name = specName, FundingStreamIds = new List <string> { "fs1" } }; pageModel.PageContext = new PageContext(); //Act IActionResult result = await pageModel.OnPostAsync(); //Assert result .Should() .BeOfType <PageResult>(); pageModel .FundingStreams .Count() .Should() .Be(1); pageModel .FundingPeriods .Count() .Should() .Be(1); pageModel .IsAuthorizedToEdit .Should().BeTrue(); }
public async Task OnGetAsync_WhenUserDoesNotHaveCreateSpecPermissionOnAllExistingFundingStream_ThenExistingFundingStreamsAvailableForList() { // Arrange Specification specification = new Specification { Id = specificationId, Name = "Test Spec", FundingStreams = new List <FundingStream> { new FundingStream { Id = "fs1", Name = "FS One" }, new FundingStream { Id = "fs2", Name = "FS Two" } }, FundingPeriod = new Reference { Id = "fp1", Name = "FP One" } }; IEnumerable <Reference> fundingPeriods = new[] { new Reference { Id = "fp1", Name = "Funding Period 1" }, new Reference { Id = "fp2", Name = "Funding Period 2" } }; IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream { Id = "fs1", Name = "FS One" }, new FundingStream { Id = "fs2", Name = "FS Two" } }; ISpecsApiClient specsClient = Substitute.For <ISpecsApiClient>(); specsClient .GetSpecification(Arg.Is(specificationId)) .Returns(new ApiResponse <Specification>(HttpStatusCode.OK, specification)); specsClient .GetFundingPeriods() .Returns(new ApiResponse <IEnumerable <Reference> >(HttpStatusCode.OK, fundingPeriods)); specsClient .GetFundingStreams() .Returns(new ApiResponse <IEnumerable <FundingStream> >(HttpStatusCode.OK, fundingStreams)); IAuthorizationHelper authorizationHelper = Substitute.For <IAuthorizationHelper>(); authorizationHelper .DoesUserHavePermission(Arg.Any <ClaimsPrincipal>(), Arg.Any <ISpecificationAuthorizationEntity>(), Arg.Is(SpecificationActionTypes.CanEditSpecification)) .Returns(true); authorizationHelper .SecurityTrimList(Arg.Any <ClaimsPrincipal>(), Arg.Any <IEnumerable <FundingStream> >(), Arg.Is(FundingStreamActionTypes.CanCreateSpecification)) .Returns(new List <FundingStream> { new FundingStream { Id = "fs1", Name = "FS One" } }); EditSpecificationPageModel pageModel = CreatePageModel(specsClient: specsClient, authorizationHelper: authorizationHelper, mapper: MappingHelper.CreateFrontEndMapper()); // Act await pageModel.OnGetAsync(specificationId); // Assert pageModel.FundingStreams.Should().HaveCount(2); }
public async Task OnGetAsync_GivenUserDoesNotHaveEditSpecificationPermission_ThenReturnPageResultWithAuthorizedToEditFlagSetToFalse() { // Arrange IEnumerable <Reference> fundingPeriods = new[] { new Reference { Id = "fp1", Name = "Funding Period 1" }, new Reference { Id = "fp2", Name = "Funding Period 2" } }; IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream { Id = "fp1", Name = "funding" } }; Specification specification = new Specification { Id = specificationId, Name = specName }; ApiResponse <IEnumerable <Reference> > fundingPeriodsResponse = new ApiResponse <IEnumerable <Reference> >(HttpStatusCode.OK, fundingPeriods); ApiResponse <IEnumerable <FundingStream> > fundingStreamsResponse = new ApiResponse <IEnumerable <FundingStream> >(HttpStatusCode.OK, fundingStreams); ApiResponse <Specification> specificationResponse = new ApiResponse <Specification>(HttpStatusCode.OK, specification); EditSpecificationViewModel viewModelReturned = CreateEditSpecificationViewModel(); ISpecsApiClient mockSpecsClient = Substitute.For <ISpecsApiClient>(); mockSpecsClient .GetSpecification(Arg.Is(specificationId)) .Returns(specificationResponse); mockSpecsClient .GetFundingPeriods() .Returns(fundingPeriodsResponse); mockSpecsClient .GetFundingStreams() .Returns(fundingStreamsResponse); IAuthorizationHelper mockAuthorizationHelper = Substitute.For <IAuthorizationHelper>(); mockAuthorizationHelper .DoesUserHavePermission(Arg.Any <ClaimsPrincipal>(), Arg.Any <ISpecificationAuthorizationEntity>(), Arg.Is(SpecificationActionTypes.CanEditSpecification)) .Returns(false); mockAuthorizationHelper .SecurityTrimList(Arg.Any <ClaimsPrincipal>(), Arg.Is(fundingStreams), Arg.Is(FundingStreamActionTypes.CanCreateSpecification)) .Returns(fundingStreams); IMapper mockMapper = CreateMapper(); mockMapper .Map <EditSpecificationViewModel>(Arg.Is(specification)) .Returns(viewModelReturned); EditSpecificationPageModel pageModel = CreatePageModel(specsClient: mockSpecsClient, authorizationHelper: mockAuthorizationHelper, mapper: mockMapper); // Act IActionResult pageResult = await pageModel.OnGetAsync(specificationId); // Assert pageResult .Should() .BeOfType <PageResult>(); pageModel .FundingStreams .Count() .Should() .Be(1); pageModel .FundingPeriods .Count() .Should() .Be(2); pageModel .EditSpecificationViewModel .OriginalSpecificationName .Should() .BeEquivalentTo(specName); pageModel .IsAuthorizedToEdit .Should().BeFalse(); }
public async Task OnGetAsync_GivenPagePopulatesAndPeriodIdProvided_ReturnsPageSetsPeriodInSelectAsDefault() { //Arrange Specification specification = new Specification { Id = specificationId, Name = specName }; EditSpecificationViewModel viewModel = CreateEditSpecificationViewModel(); IEnumerable <Reference> fundingPeriods = new[] { new Reference { Id = "fp1", Name = "Funding Period 1" }, new Reference { Id = "fp2", Name = "Funding Period 2" } }; IEnumerable <FundingStream> fundingStreams = new[] { new FundingStream { Id = "fp1", Name = "funding" } }; ApiResponse <IEnumerable <Reference> > fundingPeriodsResponse = new ApiResponse <IEnumerable <Reference> >(HttpStatusCode.OK, fundingPeriods); ApiResponse <IEnumerable <FundingStream> > fundingStreamsResponse = new ApiResponse <IEnumerable <FundingStream> >(HttpStatusCode.OK, fundingStreams); ApiResponse <Specification> specificationResponse = new ApiResponse <Specification>(HttpStatusCode.OK, specification); ISpecsApiClient apiClient = CreateApiClient(); apiClient .GetSpecification(Arg.Is(specificationId)) .Returns(specificationResponse); apiClient .GetFundingPeriods() .Returns(fundingPeriodsResponse); apiClient .GetFundingStreams() .Returns(fundingStreamsResponse); IMapper mapper = CreateMapper(); mapper .Map <EditSpecificationViewModel>(Arg.Is(specification)) .Returns(viewModel); IAuthorizationHelper authorizationHelper = Substitute.For <IAuthorizationHelper>(); authorizationHelper .DoesUserHavePermission(Arg.Any <ClaimsPrincipal>(), Arg.Any <ISpecificationAuthorizationEntity>(), Arg.Is(SpecificationActionTypes.CanEditSpecification)) .Returns(true); authorizationHelper .SecurityTrimList(Arg.Any <ClaimsPrincipal>(), Arg.Is(fundingStreams), Arg.Is(FundingStreamActionTypes.CanCreateSpecification)) .Returns(fundingStreams); EditSpecificationPageModel pageModel = CreatePageModel(apiClient, mapper, authorizationHelper); //Act IActionResult result = await pageModel.OnGetAsync(specificationId); //Assert result .Should() .BeOfType <PageResult>(); pageModel .FundingStreams .Count() .Should() .Be(1); pageModel .FundingPeriods .Count() .Should() .Be(2); pageModel .IsAuthorizedToEdit .Should().BeTrue(); viewModel .OriginalSpecificationName .Should() .BeEquivalentTo(specName); }