public async Task And_No_Option_Has_Been_Selected_And_ReservationId_Is_Null_Then_The_Validation_Errors_Are_Returned_To_The_User_And_ViewModel_Recreated( ReservationsRouteModel routeModel, GetAvailableReservationsResult availableReservationsResult, SelectReservationViewModel viewModel, string cohortDetailsUrl, [Frozen] Mock <IExternalUrlHelper> mockUrlHelper, [Frozen] Mock <IMediator> mockMediator, SelectReservationsController controller) { viewModel.SelectedReservationId = null; mockMediator .Setup(x => x.Send(It.Is <GetAvailableReservationsQuery>(c => c.AccountId.Equals(viewModel.AccountId)), It.IsAny <CancellationToken>())).ReturnsAsync(availableReservationsResult); mockUrlHelper .Setup(helper => helper.GenerateUrl( It.Is <UrlParameters>(parameters => parameters.Id == routeModel.UkPrn.ToString() && parameters.Controller == $"apprentices/{viewModel.CohortReference}" && parameters.Action == "details"))) .Returns(cohortDetailsUrl); var result = await controller.PostSelectReservation(routeModel, viewModel) as ViewResult; result.ViewName.Should().Be("Select"); var actualModel = result.Model as SelectReservationViewModel; actualModel.Should().NotBeNull(); actualModel.AvailableReservations.Should().BeEquivalentTo(availableReservationsResult.Reservations.Select(c => new AvailableReservationViewModel(c))); }
public async Task And_Has_Ukprn_And_ReservationId_And_Not_CohortRef_Then_Redirects_To_AddApprentice_With_Reservation_Details( ReservationsRouteModel routeModel, SelectReservationViewModel viewModel, GetReservationResult reservationResult, string addApprenticeUrl, [Frozen] Mock <IExternalUrlHelper> mockUrlHelper, [Frozen] Mock <IMediator> mockMediator, SelectReservationsController controller) { routeModel.CohortReference = string.Empty; viewModel.CohortReference = string.Empty; mockMediator.Setup(x => x.Send(It.Is <GetReservationQuery>(c => c.Id.Equals(viewModel.SelectedReservationId)), It.IsAny <CancellationToken>())) .ReturnsAsync(reservationResult); mockUrlHelper .Setup(helper => helper.GenerateAddApprenticeUrl(viewModel.SelectedReservationId.Value, routeModel.AccountLegalEntityPublicHashedId, reservationResult.Course.Id, routeModel.UkPrn.Value, reservationResult.StartDate, viewModel.CohortReference, routeModel.EmployerAccountId, true, string.Empty, viewModel.JourneyData)) .Returns(addApprenticeUrl); var result = await controller.PostSelectReservation(routeModel, viewModel) as RedirectResult; result.Url.Should().Be(addApprenticeUrl); }
public async Task And_Provider_Has_No_Create_Permission_Then_NoPermissions_View_Is_Shown_With_The_Back_Link_Going_To_Cohort_Details( ReservationsRouteModel routeModel, SelectReservationViewModel viewModel, GetTrustedEmployersResponse employersResponse, string cohortDetailsUrl, [Frozen] Mock <IExternalUrlHelper> mockUrlHelper, [Frozen] Mock <IMediator> mockMediator, SelectReservationsController controller) { var matchedEmployer = employersResponse.Employers.First(); routeModel.AccountLegalEntityPublicHashedId = matchedEmployer.AccountLegalEntityPublicHashedId; viewModel.SelectedReservationId = Guid.Parse(Guid.Empty.ToString().Replace("0", "9")); routeModel.Id = Guid.Empty; mockMediator .Setup(mediator => mediator.Send( It.IsAny <GetTrustedEmployersQuery>(), It.IsAny <CancellationToken>())) .ReturnsAsync(employersResponse); mockMediator.Setup(x => x.Send(It.IsAny <CacheReservationEmployerCommand>(), It.IsAny <CancellationToken>())) .ThrowsAsync(new ProviderNotAuthorisedException(viewModel.AccountId, routeModel.UkPrn.Value)); mockUrlHelper .Setup(helper => helper.GenerateCohortDetailsUrl(routeModel.UkPrn, routeModel.EmployerAccountId, routeModel.CohortReference, false, It.IsAny <string>())) .Returns(cohortDetailsUrl); //Act var result = await controller.PostSelectReservation(routeModel, viewModel) as ViewResult; //Assert result.ViewName.Should().Be("NoPermissions"); result.Model.Should().Be(cohortDetailsUrl); }
public async Task And_GlobalRule_Is_In_Place_Then_The_Funding_Paused_View_Is_Shown_For_Employer( ReservationsRouteModel routeModel, SelectReservationViewModel viewModel, GetLegalEntitiesResponse employersResponse, string cohortDetailsUrl, long expectedAccountId, [Frozen] Mock <IExternalUrlHelper> mockUrlHelper, [Frozen] Mock <IMediator> mockMediator, [Frozen] Mock <IEncodingService> encodingService, SelectReservationsController controller) { routeModel.UkPrn = null; viewModel.SelectedReservationId = Guid.Parse(Guid.Empty.ToString().Replace("0", "9")); routeModel.Id = Guid.Empty; encodingService.Setup(x => x.Decode(routeModel.EmployerAccountId, EncodingType.AccountId)).Returns(expectedAccountId); var matchedEmployer = employersResponse.AccountLegalEntities.First(); routeModel.AccountLegalEntityPublicHashedId = matchedEmployer.AccountLegalEntityPublicHashedId; mockMediator .Setup(mediator => mediator.Send( It.Is <GetLegalEntitiesQuery>(c => c.AccountId.Equals(expectedAccountId)), It.IsAny <CancellationToken>())) .ReturnsAsync(employersResponse); mockMediator.Setup(x => x.Send(It.IsAny <CacheReservationEmployerCommand>(), It.IsAny <CancellationToken>())) .ThrowsAsync(new GlobalReservationRuleException(viewModel.AccountId)); //Act var result = await controller.PostSelectReservation(routeModel, viewModel) as ViewResult; //Assert result.ViewName.Should().Be("EmployerFundingPaused"); }
public async Task And_Has_UkPrn_And_New_Reservation_Then_Redirects_To_ProviderApprenticeshipTraining_And_The_Cached_Reservation_Is_Created( ReservationsRouteModel routeModel, SelectReservationViewModel viewModel, GetTrustedEmployersResponse employersResponse, [Frozen] Mock <IMediator> mockMediator, SelectReservationsController controller) { var matchedEmployer = employersResponse.Employers.First(); routeModel.AccountLegalEntityPublicHashedId = matchedEmployer.AccountLegalEntityPublicHashedId; viewModel.SelectedReservationId = Guid.Parse(Guid.Empty.ToString().Replace("0", "9")); routeModel.Id = Guid.Empty; mockMediator.Setup(m => m.Send(It.IsAny <GetProviderCacheReservationCommandQuery>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new GetProviderCacheReservationCommandResponse { Command = new CacheReservationEmployerCommand { Id = Guid.NewGuid(), AccountId = matchedEmployer.AccountId, AccountLegalEntityPublicHashedId = matchedEmployer.AccountLegalEntityPublicHashedId, AccountLegalEntityId = matchedEmployer.AccountLegalEntityId, AccountLegalEntityName = matchedEmployer.AccountLegalEntityName, AccountName = matchedEmployer.AccountName, CohortRef = viewModel.CohortReference, UkPrn = routeModel.UkPrn.Value } }); var result = await controller.PostSelectReservation(routeModel, viewModel) as RedirectToRouteResult; result?.RouteName.Should().NotBeNull(); result.RouteName.Should().Be(RouteNames.ProviderApprenticeshipTrainingRuleCheck); result.RouteValues["ukPrn"].Should().Be(routeModel.UkPrn); result.RouteValues["id"].Should().NotBe(Guid.Empty); mockMediator.Verify(x => x.Send(It.Is <CacheReservationEmployerCommand>( c => c.CohortRef.Equals(viewModel.CohortReference) && c.AccountId.Equals(matchedEmployer.AccountId) && c.AccountLegalEntityName.Equals(matchedEmployer.AccountLegalEntityName) && c.AccountLegalEntityPublicHashedId.Equals(matchedEmployer.AccountLegalEntityPublicHashedId) && c.AccountName.Equals(matchedEmployer.AccountName) && c.UkPrn.Equals(routeModel.UkPrn) && !c.Id.Equals(Guid.Empty) && c.AccountLegalEntityId.Equals(matchedEmployer.AccountLegalEntityId)) , It.IsAny <CancellationToken>()), Times.Once); }
public void WhenIViewTheSelectReservationScreen() { var controller = Services.GetService <SelectReservationsController>(); var claim = new Claim(EmployerClaims.IdamsUserIdClaimTypeIdentifier, TestData.UserId.ToString()); var apiClient = Services.GetService <IApiClient>(); var mock = Mock.Get(apiClient); controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { claim })); mock.Setup(x => x.GetAll <GetReservationResponse>( It.IsAny <ReservationApiRequest>())).ReturnsAsync(TestData.Reservations); _actionResult = controller.SelectReservation(TestData.ReservationRouteModel, _viewModel).Result; var actual = _actionResult as ViewResult; _actualModel = actual?.Model as SelectReservationViewModel; }
public async Task And_Is_An_Employer_And_New_Reservation_Then_Redirects_To_EmployerApprenticeshipTraining_And_The_Cached_Reservation_Is_Created( ReservationsRouteModel routeModel, SelectReservationViewModel viewModel, long expectedAccountId, GetLegalEntitiesResponse employersResponse, [Frozen] Mock <IMediator> mockMediator, [Frozen] Mock <IEncodingService> encodingService, SelectReservationsController controller) { viewModel.SelectedReservationId = Guid.Parse(Guid.Empty.ToString().Replace("0", "9")); routeModel.Id = Guid.Empty; routeModel.UkPrn = null; encodingService.Setup(x => x.Decode(routeModel.EmployerAccountId, EncodingType.AccountId)).Returns(expectedAccountId); var matchedEmployer = employersResponse.AccountLegalEntities.First(); routeModel.AccountLegalEntityPublicHashedId = matchedEmployer.AccountLegalEntityPublicHashedId; mockMediator .Setup(mediator => mediator.Send( It.Is <GetLegalEntitiesQuery>(c => c.AccountId.Equals(expectedAccountId)), It.IsAny <CancellationToken>())) .ReturnsAsync(employersResponse); var result = await controller.PostSelectReservation(routeModel, viewModel) as RedirectToRouteResult; result?.RouteName.Should().NotBeNull(); result.RouteName.Should().Be(RouteNames.EmployerSelectCourseRuleCheck); result.RouteValues["EmployerAccountId"].Should().Be(routeModel.EmployerAccountId); result.RouteValues["id"].Should().NotBe(Guid.Empty); mockMediator.Verify(x => x.Send(It.Is <CacheReservationEmployerCommand>( c => c.CohortRef.Equals(viewModel.CohortReference) && c.AccountId.Equals(expectedAccountId) && c.AccountLegalEntityName.Equals(matchedEmployer.AccountLegalEntityName) && c.AccountLegalEntityPublicHashedId.Equals(matchedEmployer.AccountLegalEntityPublicHashedId) && !c.Id.Equals(Guid.Empty) && c.AccountLegalEntityId.Equals(matchedEmployer.AccountLegalEntityId)) , It.IsAny <CancellationToken>()), Times.Once); }
public async Task <IActionResult> SelectReservation( ReservationsRouteModel routeModel, SelectReservationViewModel viewModel) { var backUrl = _urlHelper.GenerateCohortDetailsUrl(routeModel.UkPrn, routeModel.EmployerAccountId, viewModel.CohortReference, journeyData: viewModel.JourneyData); try { var apprenticeshipTrainingRouteName = RouteNames.EmployerSelectCourseRuleCheck; CacheReservationEmployerCommand cacheReservationEmployerCommand; Guid?userId = null; if (routeModel.UkPrn.HasValue) { var response = await _mediator.Send(new GetProviderCacheReservationCommandQuery { AccountLegalEntityPublicHashedId = routeModel.AccountLegalEntityPublicHashedId, CohortRef = routeModel.CohortReference, CohortId = _encodingService.Decode(routeModel.CohortReference, EncodingType.CohortReference), UkPrn = routeModel.UkPrn.Value }); cacheReservationEmployerCommand = response.Command; apprenticeshipTrainingRouteName = RouteNames.ProviderApprenticeshipTrainingRuleCheck; } else { var userAccountIdClaim = HttpContext.User.Claims.First(c => c.Type.Equals(EmployerClaims.IdamsUserIdClaimTypeIdentifier)); userId = Guid.Parse(userAccountIdClaim.Value); cacheReservationEmployerCommand = await BuildEmployerReservationCacheCommand( routeModel.EmployerAccountId, routeModel.AccountLegalEntityPublicHashedId, viewModel.CohortReference, viewModel.ProviderId, viewModel.JourneyData); } var redirectResult = await CheckCanAutoReserve(cacheReservationEmployerCommand.AccountId, viewModel.TransferSenderId, viewModel.JourneyData, cacheReservationEmployerCommand.AccountLegalEntityPublicHashedId, routeModel.UkPrn ?? viewModel.ProviderId, viewModel.CohortReference, routeModel.EmployerAccountId, userId); if (!string.IsNullOrEmpty(redirectResult)) { if (redirectResult == RouteNames.Error500) { return(RedirectToRoute(redirectResult)); } return(Redirect(redirectResult)); } var availableReservationsResult = await _mediator.Send( new GetAvailableReservationsQuery { AccountId = cacheReservationEmployerCommand.AccountId }); if (availableReservationsResult.Reservations != null && availableReservationsResult.Reservations.Any()) { viewModel.AvailableReservations = availableReservationsResult.Reservations .Select(reservation => new AvailableReservationViewModel(reservation)); viewModel.AccountId = cacheReservationEmployerCommand.AccountId; viewModel.BackLink = backUrl; return(View(ViewNames.Select, viewModel)); } await _mediator.Send(cacheReservationEmployerCommand); routeModel.Id = cacheReservationEmployerCommand.Id; return(RedirectToRoute(apprenticeshipTrainingRouteName, routeModel)); } catch (ValidationException e) { _logger.LogWarning(e, "Validation error trying to render select reservation."); return(RedirectToRoute(RouteNames.Error500)); } catch (ProviderNotAuthorisedException e) { _logger.LogWarning(e, $"Provider (UKPRN: {e.UkPrn}) does not has access to create a reservation for legal entity for account (Id: {e.AccountId})."); return(View("NoPermissions", backUrl)); } catch (ReservationLimitReachedException) { return(View("ReservationLimitReached", backUrl)); } catch (GlobalReservationRuleException) { if (routeModel.UkPrn.HasValue) { return(View("ProviderFundingPaused", backUrl)); } return(View("EmployerFundingPaused", backUrl)); } catch (AccountLegalEntityNotFoundException e) { _logger.LogWarning($"Account legal entity not found [{e.AccountLegalEntityPublicHashedId}]."); return(RedirectToRoute(RouteNames.Error404)); } catch (AccountLegalEntityInvalidException ex) { _logger.LogWarning(ex.Message); return(RedirectToRoute(RouteNames.Error500)); } catch (TransferSenderNotAllowedException e) { _logger.LogWarning(e, $"AccountId: {e.AccountId} does not have sender id {e.TransferSenderId} allowed)."); return(RedirectToRoute(RouteNames.Error500)); } catch (EmployerAgreementNotSignedException e) { _logger.LogWarning(e, $"AccountId: {e.AccountId} does not have a signed agreement for ALE {e.AccountLegalEntityId})."); var routeName = RouteNames.EmployerTransactorSignAgreement; if (routeModel.UkPrn.HasValue) { routeName = RouteNames.ProviderEmployerAgreementNotSigned; } else { if (_userClaimsService.UserIsInRole(routeModel.EmployerAccountId, EmployerUserRole.Owner, User.Claims)) { routeName = RouteNames.EmployerOwnerSignAgreement; } } routeModel.IsFromSelect = true; routeModel.PreviousPage = backUrl; return(RedirectToRoute(routeName, routeModel)); } catch (Exception e) { _logger.LogError(e, "Error trying to render select reservation."); return(RedirectToRoute(RouteNames.Error500)); } }
public async Task <IActionResult> PostSelectReservation( ReservationsRouteModel routeModel, SelectReservationViewModel viewModel) { var backUrl = _urlHelper.GenerateCohortDetailsUrl(routeModel.UkPrn, routeModel.EmployerAccountId, routeModel.CohortReference, journeyData: viewModel.JourneyData); if (!viewModel.SelectedReservationId.HasValue || viewModel.SelectedReservationId == Guid.Empty) { var availableReservationsResult = await _mediator.Send( new GetAvailableReservationsQuery { AccountId = viewModel.AccountId }); viewModel.AvailableReservations = availableReservationsResult.Reservations .Select(reservation => new AvailableReservationViewModel(reservation)); ModelState.AddModelError(nameof(viewModel.SelectedReservationId), "Select an option"); viewModel.BackLink = backUrl; return(View(ViewNames.Select, viewModel)); } if (viewModel.SelectedReservationId != Guid.Empty && viewModel.SelectedReservationId != Guid.Parse(Guid.Empty.ToString().Replace("0", "9"))) { var reservation = await _mediator.Send(new GetReservationQuery { Id = viewModel.SelectedReservationId.Value }); var url = _urlHelper.GenerateAddApprenticeUrl(viewModel.SelectedReservationId.Value, routeModel.AccountLegalEntityPublicHashedId, reservation.Course.Id, routeModel.UkPrn ?? viewModel.ProviderId, reservation.StartDate, viewModel.CohortReference, routeModel.EmployerAccountId, string.IsNullOrEmpty(viewModel.CohortReference), journeyData: viewModel.JourneyData); var addApprenticeUrl = url; return(Redirect(addApprenticeUrl)); } try { CacheReservationEmployerCommand cacheReservationEmployerCommand; if (routeModel.UkPrn.HasValue) { var response = await _mediator.Send(new GetProviderCacheReservationCommandQuery { AccountLegalEntityPublicHashedId = routeModel.AccountLegalEntityPublicHashedId, CohortRef = routeModel.CohortReference, CohortId = _encodingService.Decode(routeModel.CohortReference, EncodingType.CohortReference), UkPrn = routeModel.UkPrn.Value }); cacheReservationEmployerCommand = response.Command; } else { cacheReservationEmployerCommand = await BuildEmployerReservationCacheCommand( routeModel.EmployerAccountId, routeModel.AccountLegalEntityPublicHashedId, viewModel.CohortReference, viewModel.ProviderId, viewModel.JourneyData); } await _mediator.Send(cacheReservationEmployerCommand); routeModel.Id = cacheReservationEmployerCommand.Id; } catch (ReservationLimitReachedException) { return(View("ReservationLimitReached", backUrl)); } catch (ProviderNotAuthorisedException e) { _logger.LogWarning(e, $"Provider (UKPRN: {e.UkPrn}) does not has access to create a reservation for legal entity for account (Id: {e.AccountId})."); return(View("NoPermissions", backUrl)); } catch (GlobalReservationRuleException) { if (routeModel.UkPrn.HasValue) { return(View("ProviderFundingPaused", backUrl)); } return(View("EmployerFundingPaused", backUrl)); } var routeName = RouteNames.ProviderApprenticeshipTrainingRuleCheck; if (!routeModel.UkPrn.HasValue) { routeName = RouteNames.EmployerSelectCourseRuleCheck; } return(RedirectToRoute(routeName, routeModel)); }
public EmployerSelectReservationSteps(TestServiceProvider serviceProvider, TestData testData) : base(serviceProvider, testData) { _viewModel = new SelectReservationViewModel(); }